xref: /freebsd/lib/libpmc/libpmc.c (revision 3ef90571c1feac738dd60ea1516df2f974f18b56)
1 /*-
2  * Copyright (c) 2003-2008 Joseph Koshy
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/module.h>
33 #include <sys/pmc.h>
34 #include <sys/syscall.h>
35 
36 #include <ctype.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <pmc.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <strings.h>
44 #include <unistd.h>
45 
46 #include "libpmcinternal.h"
47 
48 /* Function prototypes */
49 #if defined(__i386__)
50 static int k7_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
51     struct pmc_op_pmcallocate *_pmc_config);
52 #endif
53 #if defined(__amd64__) || defined(__i386__)
54 static int iaf_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
55     struct pmc_op_pmcallocate *_pmc_config);
56 static int iap_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
57     struct pmc_op_pmcallocate *_pmc_config);
58 static int ucf_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
59     struct pmc_op_pmcallocate *_pmc_config);
60 static int ucp_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
61     struct pmc_op_pmcallocate *_pmc_config);
62 static int k8_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
63     struct pmc_op_pmcallocate *_pmc_config);
64 static int p4_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
65     struct pmc_op_pmcallocate *_pmc_config);
66 #endif
67 #if defined(__i386__)
68 static int p5_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
69     struct pmc_op_pmcallocate *_pmc_config);
70 static int p6_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
71     struct pmc_op_pmcallocate *_pmc_config);
72 #endif
73 #if defined(__amd64__) || defined(__i386__)
74 static int tsc_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
75     struct pmc_op_pmcallocate *_pmc_config);
76 #endif
77 #if defined(__arm__)
78 #if defined(__XSCALE__)
79 static int xscale_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
80     struct pmc_op_pmcallocate *_pmc_config);
81 #endif
82 static int armv7_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
83     struct pmc_op_pmcallocate *_pmc_config);
84 #endif
85 #if defined(__aarch64__)
86 static int arm64_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
87     struct pmc_op_pmcallocate *_pmc_config);
88 #endif
89 #if defined(__mips__)
90 static int mips_allocate_pmc(enum pmc_event _pe, char* ctrspec,
91 			     struct pmc_op_pmcallocate *_pmc_config);
92 #endif /* __mips__ */
93 static int soft_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
94     struct pmc_op_pmcallocate *_pmc_config);
95 
96 #if defined(__powerpc__)
97 static int powerpc_allocate_pmc(enum pmc_event _pe, char* ctrspec,
98 			     struct pmc_op_pmcallocate *_pmc_config);
99 #endif /* __powerpc__ */
100 
101 #define PMC_CALL(cmd, params)				\
102 	syscall(pmc_syscall, PMC_OP_##cmd, (params))
103 
104 /*
105  * Event aliases provide a way for the user to ask for generic events
106  * like "cache-misses", or "instructions-retired".  These aliases are
107  * mapped to the appropriate canonical event descriptions using a
108  * lookup table.
109  */
110 struct pmc_event_alias {
111 	const char	*pm_alias;
112 	const char	*pm_spec;
113 };
114 
115 static const struct pmc_event_alias *pmc_mdep_event_aliases;
116 
117 /*
118  * The pmc_event_descr structure maps symbolic names known to the user
119  * to integer codes used by the PMC KLD.
120  */
121 struct pmc_event_descr {
122 	const char	*pm_ev_name;
123 	enum pmc_event	pm_ev_code;
124 };
125 
126 /*
127  * The pmc_class_descr structure maps class name prefixes for
128  * event names to event tables and other PMC class data.
129  */
130 struct pmc_class_descr {
131 	const char	*pm_evc_name;
132 	size_t		pm_evc_name_size;
133 	enum pmc_class	pm_evc_class;
134 	const struct pmc_event_descr *pm_evc_event_table;
135 	size_t		pm_evc_event_table_size;
136 	int		(*pm_evc_allocate_pmc)(enum pmc_event _pe,
137 			    char *_ctrspec, struct pmc_op_pmcallocate *_pa);
138 };
139 
140 #define	PMC_TABLE_SIZE(N)	(sizeof(N)/sizeof(N[0]))
141 #define	PMC_EVENT_TABLE_SIZE(N)	PMC_TABLE_SIZE(N##_event_table)
142 
143 #undef	__PMC_EV
144 #define	__PMC_EV(C,N) { #N, PMC_EV_ ## C ## _ ## N },
145 
146 /*
147  * PMC_CLASSDEP_TABLE(NAME, CLASS)
148  *
149  * Define a table mapping event names and aliases to HWPMC event IDs.
150  */
151 #define	PMC_CLASSDEP_TABLE(N, C)				\
152 	static const struct pmc_event_descr N##_event_table[] =	\
153 	{							\
154 		__PMC_EV_##C()					\
155 	}
156 
157 PMC_CLASSDEP_TABLE(iaf, IAF);
158 PMC_CLASSDEP_TABLE(k7, K7);
159 PMC_CLASSDEP_TABLE(k8, K8);
160 PMC_CLASSDEP_TABLE(p4, P4);
161 PMC_CLASSDEP_TABLE(p5, P5);
162 PMC_CLASSDEP_TABLE(p6, P6);
163 PMC_CLASSDEP_TABLE(xscale, XSCALE);
164 PMC_CLASSDEP_TABLE(armv7, ARMV7);
165 PMC_CLASSDEP_TABLE(armv8, ARMV8);
166 PMC_CLASSDEP_TABLE(mips24k, MIPS24K);
167 PMC_CLASSDEP_TABLE(mips74k, MIPS74K);
168 PMC_CLASSDEP_TABLE(octeon, OCTEON);
169 PMC_CLASSDEP_TABLE(ucf, UCF);
170 PMC_CLASSDEP_TABLE(ppc7450, PPC7450);
171 PMC_CLASSDEP_TABLE(ppc970, PPC970);
172 PMC_CLASSDEP_TABLE(e500, E500);
173 
174 static struct pmc_event_descr soft_event_table[PMC_EV_DYN_COUNT];
175 
176 #undef	__PMC_EV_ALIAS
177 #define	__PMC_EV_ALIAS(N,CODE) 	{ N, PMC_EV_##CODE },
178 
179 static const struct pmc_event_descr atom_event_table[] =
180 {
181 	__PMC_EV_ALIAS_ATOM()
182 };
183 
184 static const struct pmc_event_descr atom_silvermont_event_table[] =
185 {
186 	__PMC_EV_ALIAS_ATOM_SILVERMONT()
187 };
188 
189 static const struct pmc_event_descr core_event_table[] =
190 {
191 	__PMC_EV_ALIAS_CORE()
192 };
193 
194 
195 static const struct pmc_event_descr core2_event_table[] =
196 {
197 	__PMC_EV_ALIAS_CORE2()
198 };
199 
200 static const struct pmc_event_descr corei7_event_table[] =
201 {
202 	__PMC_EV_ALIAS_COREI7()
203 };
204 
205 static const struct pmc_event_descr nehalem_ex_event_table[] =
206 {
207 	__PMC_EV_ALIAS_COREI7()
208 };
209 
210 static const struct pmc_event_descr haswell_event_table[] =
211 {
212 	__PMC_EV_ALIAS_HASWELL()
213 };
214 
215 static const struct pmc_event_descr haswell_xeon_event_table[] =
216 {
217 	__PMC_EV_ALIAS_HASWELL_XEON()
218 };
219 
220 
221 static const struct pmc_event_descr ivybridge_event_table[] =
222 {
223 	__PMC_EV_ALIAS_IVYBRIDGE()
224 };
225 
226 static const struct pmc_event_descr ivybridge_xeon_event_table[] =
227 {
228 	__PMC_EV_ALIAS_IVYBRIDGE_XEON()
229 };
230 
231 static const struct pmc_event_descr sandybridge_event_table[] =
232 {
233 	__PMC_EV_ALIAS_SANDYBRIDGE()
234 };
235 
236 static const struct pmc_event_descr sandybridge_xeon_event_table[] =
237 {
238 	__PMC_EV_ALIAS_SANDYBRIDGE_XEON()
239 };
240 
241 static const struct pmc_event_descr westmere_event_table[] =
242 {
243 	__PMC_EV_ALIAS_WESTMERE()
244 };
245 
246 static const struct pmc_event_descr westmere_ex_event_table[] =
247 {
248 	__PMC_EV_ALIAS_WESTMERE()
249 };
250 
251 static const struct pmc_event_descr corei7uc_event_table[] =
252 {
253 	__PMC_EV_ALIAS_COREI7UC()
254 };
255 
256 static const struct pmc_event_descr haswelluc_event_table[] =
257 {
258 	__PMC_EV_ALIAS_HASWELLUC()
259 };
260 
261 static const struct pmc_event_descr sandybridgeuc_event_table[] =
262 {
263 	__PMC_EV_ALIAS_SANDYBRIDGEUC()
264 };
265 
266 static const struct pmc_event_descr westmereuc_event_table[] =
267 {
268 	__PMC_EV_ALIAS_WESTMEREUC()
269 };
270 
271 static const struct pmc_event_descr cortex_a53_event_table[] =
272 {
273 	__PMC_EV_ALIAS_ARMV8_CORTEX_A53()
274 };
275 
276 static const struct pmc_event_descr cortex_a57_event_table[] =
277 {
278 	__PMC_EV_ALIAS_ARMV8_CORTEX_A57()
279 };
280 
281 /*
282  * PMC_MDEP_TABLE(NAME, PRIMARYCLASS, ADDITIONAL_CLASSES...)
283  *
284  * Map a CPU to the PMC classes it supports.
285  */
286 #define	PMC_MDEP_TABLE(N,C,...)				\
287 	static const enum pmc_class N##_pmc_classes[] = {	\
288 		PMC_CLASS_##C, __VA_ARGS__			\
289 	}
290 
291 PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
292 PMC_MDEP_TABLE(atom_silvermont, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
293 PMC_MDEP_TABLE(core, IAP, PMC_CLASS_SOFT, PMC_CLASS_TSC);
294 PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
295 PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
296 PMC_MDEP_TABLE(nehalem_ex, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
297 PMC_MDEP_TABLE(haswell, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
298 PMC_MDEP_TABLE(haswell_xeon, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
299 PMC_MDEP_TABLE(ivybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
300 PMC_MDEP_TABLE(ivybridge_xeon, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
301 PMC_MDEP_TABLE(sandybridge, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
302 PMC_MDEP_TABLE(sandybridge_xeon, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
303 PMC_MDEP_TABLE(westmere, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC, PMC_CLASS_UCF, PMC_CLASS_UCP);
304 PMC_MDEP_TABLE(westmere_ex, IAP, PMC_CLASS_SOFT, PMC_CLASS_IAF, PMC_CLASS_TSC);
305 PMC_MDEP_TABLE(k7, K7, PMC_CLASS_SOFT, PMC_CLASS_TSC);
306 PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC);
307 PMC_MDEP_TABLE(p4, P4, PMC_CLASS_SOFT, PMC_CLASS_TSC);
308 PMC_MDEP_TABLE(p5, P5, PMC_CLASS_SOFT, PMC_CLASS_TSC);
309 PMC_MDEP_TABLE(p6, P6, PMC_CLASS_SOFT, PMC_CLASS_TSC);
310 PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE);
311 PMC_MDEP_TABLE(armv7, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7);
312 PMC_MDEP_TABLE(cortex_a53, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8);
313 PMC_MDEP_TABLE(cortex_a57, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8);
314 PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K);
315 PMC_MDEP_TABLE(mips74k, MIPS74K, PMC_CLASS_SOFT, PMC_CLASS_MIPS74K);
316 PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON);
317 PMC_MDEP_TABLE(ppc7450, PPC7450, PMC_CLASS_SOFT, PMC_CLASS_PPC7450, PMC_CLASS_TSC);
318 PMC_MDEP_TABLE(ppc970, PPC970, PMC_CLASS_SOFT, PMC_CLASS_PPC970, PMC_CLASS_TSC);
319 PMC_MDEP_TABLE(e500, E500, PMC_CLASS_SOFT, PMC_CLASS_E500, PMC_CLASS_TSC);
320 PMC_MDEP_TABLE(generic, SOFT, PMC_CLASS_SOFT);
321 
322 static const struct pmc_event_descr tsc_event_table[] =
323 {
324 	__PMC_EV_TSC()
325 };
326 
327 #undef	PMC_CLASS_TABLE_DESC
328 #define	PMC_CLASS_TABLE_DESC(NAME, CLASS, EVENTS, ALLOCATOR)	\
329 static const struct pmc_class_descr NAME##_class_table_descr =	\
330 	{							\
331 		.pm_evc_name  = #CLASS "-",			\
332 		.pm_evc_name_size = sizeof(#CLASS "-") - 1,	\
333 		.pm_evc_class = PMC_CLASS_##CLASS ,		\
334 		.pm_evc_event_table = EVENTS##_event_table ,	\
335 		.pm_evc_event_table_size = 			\
336 			PMC_EVENT_TABLE_SIZE(EVENTS),		\
337 		.pm_evc_allocate_pmc = ALLOCATOR##_allocate_pmc	\
338 	}
339 
340 #if	defined(__i386__) || defined(__amd64__)
341 PMC_CLASS_TABLE_DESC(iaf, IAF, iaf, iaf);
342 PMC_CLASS_TABLE_DESC(atom, IAP, atom, iap);
343 PMC_CLASS_TABLE_DESC(atom_silvermont, IAP, atom_silvermont, iap);
344 PMC_CLASS_TABLE_DESC(core, IAP, core, iap);
345 PMC_CLASS_TABLE_DESC(core2, IAP, core2, iap);
346 PMC_CLASS_TABLE_DESC(corei7, IAP, corei7, iap);
347 PMC_CLASS_TABLE_DESC(nehalem_ex, IAP, nehalem_ex, iap);
348 PMC_CLASS_TABLE_DESC(haswell, IAP, haswell, iap);
349 PMC_CLASS_TABLE_DESC(haswell_xeon, IAP, haswell_xeon, iap);
350 PMC_CLASS_TABLE_DESC(ivybridge, IAP, ivybridge, iap);
351 PMC_CLASS_TABLE_DESC(ivybridge_xeon, IAP, ivybridge_xeon, iap);
352 PMC_CLASS_TABLE_DESC(sandybridge, IAP, sandybridge, iap);
353 PMC_CLASS_TABLE_DESC(sandybridge_xeon, IAP, sandybridge_xeon, iap);
354 PMC_CLASS_TABLE_DESC(westmere, IAP, westmere, iap);
355 PMC_CLASS_TABLE_DESC(westmere_ex, IAP, westmere_ex, iap);
356 PMC_CLASS_TABLE_DESC(ucf, UCF, ucf, ucf);
357 PMC_CLASS_TABLE_DESC(corei7uc, UCP, corei7uc, ucp);
358 PMC_CLASS_TABLE_DESC(haswelluc, UCP, haswelluc, ucp);
359 PMC_CLASS_TABLE_DESC(sandybridgeuc, UCP, sandybridgeuc, ucp);
360 PMC_CLASS_TABLE_DESC(westmereuc, UCP, westmereuc, ucp);
361 #endif
362 #if	defined(__i386__)
363 PMC_CLASS_TABLE_DESC(k7, K7, k7, k7);
364 #endif
365 #if	defined(__i386__) || defined(__amd64__)
366 PMC_CLASS_TABLE_DESC(k8, K8, k8, k8);
367 PMC_CLASS_TABLE_DESC(p4, P4, p4, p4);
368 #endif
369 #if	defined(__i386__)
370 PMC_CLASS_TABLE_DESC(p5, P5, p5, p5);
371 PMC_CLASS_TABLE_DESC(p6, P6, p6, p6);
372 #endif
373 #if	defined(__i386__) || defined(__amd64__)
374 PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc);
375 #endif
376 #if	defined(__arm__)
377 #if	defined(__XSCALE__)
378 PMC_CLASS_TABLE_DESC(xscale, XSCALE, xscale, xscale);
379 #endif
380 PMC_CLASS_TABLE_DESC(armv7, ARMV7, armv7, armv7);
381 #endif
382 #if	defined(__aarch64__)
383 PMC_CLASS_TABLE_DESC(cortex_a53, ARMV8, cortex_a53, arm64);
384 PMC_CLASS_TABLE_DESC(cortex_a57, ARMV8, cortex_a57, arm64);
385 #endif
386 #if defined(__mips__)
387 PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips);
388 PMC_CLASS_TABLE_DESC(mips74k, MIPS74K, mips74k, mips);
389 PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips);
390 #endif /* __mips__ */
391 #if defined(__powerpc__)
392 PMC_CLASS_TABLE_DESC(ppc7450, PPC7450, ppc7450, powerpc);
393 PMC_CLASS_TABLE_DESC(ppc970, PPC970, ppc970, powerpc);
394 PMC_CLASS_TABLE_DESC(e500, E500, e500, powerpc);
395 #endif
396 
397 static struct pmc_class_descr soft_class_table_descr =
398 {
399 	.pm_evc_name  = "SOFT-",
400 	.pm_evc_name_size = sizeof("SOFT-") - 1,
401 	.pm_evc_class = PMC_CLASS_SOFT,
402 	.pm_evc_event_table = NULL,
403 	.pm_evc_event_table_size = 0,
404 	.pm_evc_allocate_pmc = soft_allocate_pmc
405 };
406 
407 #undef	PMC_CLASS_TABLE_DESC
408 
409 static const struct pmc_class_descr **pmc_class_table;
410 #define	PMC_CLASS_TABLE_SIZE	cpu_info.pm_nclass
411 
412 static const enum pmc_class *pmc_mdep_class_list;
413 static size_t pmc_mdep_class_list_size;
414 
415 /*
416  * Mapping tables, mapping enumeration values to human readable
417  * strings.
418  */
419 
420 static const char * pmc_capability_names[] = {
421 #undef	__PMC_CAP
422 #define	__PMC_CAP(N,V,D)	#N ,
423 	__PMC_CAPS()
424 };
425 
426 struct pmc_class_map {
427 	enum pmc_class	pm_class;
428 	const char	*pm_name;
429 };
430 
431 static const struct pmc_class_map pmc_class_names[] = {
432 #undef	__PMC_CLASS
433 #define __PMC_CLASS(S,V,D) { .pm_class = PMC_CLASS_##S, .pm_name = #S } ,
434 	__PMC_CLASSES()
435 };
436 
437 struct pmc_cputype_map {
438 	enum pmc_cputype pm_cputype;
439 	const char	*pm_name;
440 };
441 
442 static const struct pmc_cputype_map pmc_cputype_names[] = {
443 #undef	__PMC_CPU
444 #define	__PMC_CPU(S, V, D) { .pm_cputype = PMC_CPU_##S, .pm_name = #S } ,
445 	__PMC_CPUS()
446 };
447 
448 static const char * pmc_disposition_names[] = {
449 #undef	__PMC_DISP
450 #define	__PMC_DISP(D)	#D ,
451 	__PMC_DISPOSITIONS()
452 };
453 
454 static const char * pmc_mode_names[] = {
455 #undef  __PMC_MODE
456 #define __PMC_MODE(M,N)	#M ,
457 	__PMC_MODES()
458 };
459 
460 static const char * pmc_state_names[] = {
461 #undef  __PMC_STATE
462 #define __PMC_STATE(S) #S ,
463 	__PMC_STATES()
464 };
465 
466 /*
467  * Filled in by pmc_init().
468  */
469 static int pmc_syscall = -1;
470 static struct pmc_cpuinfo cpu_info;
471 static struct pmc_op_getdyneventinfo soft_event_info;
472 
473 /* Event masks for events */
474 struct pmc_masks {
475 	const char	*pm_name;
476 	const uint64_t	pm_value;
477 };
478 #define	PMCMASK(N,V)	{ .pm_name = #N, .pm_value = (V) }
479 #define	NULLMASK	{ .pm_name = NULL }
480 
481 #if defined(__amd64__) || defined(__i386__)
482 static int
483 pmc_parse_mask(const struct pmc_masks *pmask, char *p, uint64_t *evmask)
484 {
485 	const struct pmc_masks *pm;
486 	char *q, *r;
487 	int c;
488 
489 	if (pmask == NULL)	/* no mask keywords */
490 		return (-1);
491 	q = strchr(p, '=');	/* skip '=' */
492 	if (*++q == '\0')	/* no more data */
493 		return (-1);
494 	c = 0;			/* count of mask keywords seen */
495 	while ((r = strsep(&q, "+")) != NULL) {
496 		for (pm = pmask; pm->pm_name && strcasecmp(r, pm->pm_name);
497 		    pm++)
498 			;
499 		if (pm->pm_name == NULL) /* not found */
500 			return (-1);
501 		*evmask |= pm->pm_value;
502 		c++;
503 	}
504 	return (c);
505 }
506 #endif
507 
508 #define	KWMATCH(p,kw)		(strcasecmp((p), (kw)) == 0)
509 #define	KWPREFIXMATCH(p,kw)	(strncasecmp((p), (kw), sizeof((kw)) - 1) == 0)
510 #define	EV_ALIAS(N,S)		{ .pm_alias = N, .pm_spec = S }
511 
512 #if defined(__i386__)
513 
514 /*
515  * AMD K7 (Athlon) CPUs.
516  */
517 
518 static struct pmc_event_alias k7_aliases[] = {
519 	EV_ALIAS("branches",		"k7-retired-branches"),
520 	EV_ALIAS("branch-mispredicts",	"k7-retired-branches-mispredicted"),
521 	EV_ALIAS("cycles",		"tsc"),
522 	EV_ALIAS("dc-misses",		"k7-dc-misses"),
523 	EV_ALIAS("ic-misses",		"k7-ic-misses"),
524 	EV_ALIAS("instructions",	"k7-retired-instructions"),
525 	EV_ALIAS("interrupts",		"k7-hardware-interrupts"),
526 	EV_ALIAS(NULL, NULL)
527 };
528 
529 #define	K7_KW_COUNT	"count"
530 #define	K7_KW_EDGE	"edge"
531 #define	K7_KW_INV	"inv"
532 #define	K7_KW_OS	"os"
533 #define	K7_KW_UNITMASK	"unitmask"
534 #define	K7_KW_USR	"usr"
535 
536 static int
537 k7_allocate_pmc(enum pmc_event pe, char *ctrspec,
538     struct pmc_op_pmcallocate *pmc_config)
539 {
540 	char		*e, *p, *q;
541 	int		c, has_unitmask;
542 	uint32_t	count, unitmask;
543 
544 	pmc_config->pm_md.pm_amd.pm_amd_config = 0;
545 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
546 
547 	if (pe == PMC_EV_K7_DC_REFILLS_FROM_L2 ||
548 	    pe == PMC_EV_K7_DC_REFILLS_FROM_SYSTEM ||
549 	    pe == PMC_EV_K7_DC_WRITEBACKS) {
550 		has_unitmask = 1;
551 		unitmask = AMD_PMC_UNITMASK_MOESI;
552 	} else
553 		unitmask = has_unitmask = 0;
554 
555 	while ((p = strsep(&ctrspec, ",")) != NULL) {
556 		if (KWPREFIXMATCH(p, K7_KW_COUNT "=")) {
557 			q = strchr(p, '=');
558 			if (*++q == '\0') /* skip '=' */
559 				return (-1);
560 
561 			count = strtol(q, &e, 0);
562 			if (e == q || *e != '\0')
563 				return (-1);
564 
565 			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
566 			pmc_config->pm_md.pm_amd.pm_amd_config |=
567 			    AMD_PMC_TO_COUNTER(count);
568 
569 		} else if (KWMATCH(p, K7_KW_EDGE)) {
570 			pmc_config->pm_caps |= PMC_CAP_EDGE;
571 		} else if (KWMATCH(p, K7_KW_INV)) {
572 			pmc_config->pm_caps |= PMC_CAP_INVERT;
573 		} else if (KWMATCH(p, K7_KW_OS)) {
574 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
575 		} else if (KWPREFIXMATCH(p, K7_KW_UNITMASK "=")) {
576 			if (has_unitmask == 0)
577 				return (-1);
578 			unitmask = 0;
579 			q = strchr(p, '=');
580 			if (*++q == '\0') /* skip '=' */
581 				return (-1);
582 
583 			while ((c = tolower(*q++)) != 0)
584 				if (c == 'm')
585 					unitmask |= AMD_PMC_UNITMASK_M;
586 				else if (c == 'o')
587 					unitmask |= AMD_PMC_UNITMASK_O;
588 				else if (c == 'e')
589 					unitmask |= AMD_PMC_UNITMASK_E;
590 				else if (c == 's')
591 					unitmask |= AMD_PMC_UNITMASK_S;
592 				else if (c == 'i')
593 					unitmask |= AMD_PMC_UNITMASK_I;
594 				else if (c == '+')
595 					continue;
596 				else
597 					return (-1);
598 
599 			if (unitmask == 0)
600 				return (-1);
601 
602 		} else if (KWMATCH(p, K7_KW_USR)) {
603 			pmc_config->pm_caps |= PMC_CAP_USER;
604 		} else
605 			return (-1);
606 	}
607 
608 	if (has_unitmask) {
609 		pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
610 		pmc_config->pm_md.pm_amd.pm_amd_config |=
611 		    AMD_PMC_TO_UNITMASK(unitmask);
612 	}
613 
614 	return (0);
615 
616 }
617 
618 #endif
619 
620 #if defined(__amd64__) || defined(__i386__)
621 
622 /*
623  * Intel Core (Family 6, Model E) PMCs.
624  */
625 
626 static struct pmc_event_alias core_aliases[] = {
627 	EV_ALIAS("branches",		"iap-br-instr-ret"),
628 	EV_ALIAS("branch-mispredicts",	"iap-br-mispred-ret"),
629 	EV_ALIAS("cycles",		"tsc-tsc"),
630 	EV_ALIAS("ic-misses",		"iap-icache-misses"),
631 	EV_ALIAS("instructions",	"iap-instr-ret"),
632 	EV_ALIAS("interrupts",		"iap-core-hw-int-rx"),
633 	EV_ALIAS("unhalted-cycles",	"iap-unhalted-core-cycles"),
634 	EV_ALIAS(NULL, NULL)
635 };
636 
637 /*
638  * Intel Core2 (Family 6, Model F), Core2Extreme (Family 6, Model 17H)
639  * and Atom (Family 6, model 1CH) PMCs.
640  *
641  * We map aliases to events on the fixed-function counters if these
642  * are present.  Note that not all CPUs in this family contain fixed-function
643  * counters.
644  */
645 
646 static struct pmc_event_alias core2_aliases[] = {
647 	EV_ALIAS("branches",		"iap-br-inst-retired.any"),
648 	EV_ALIAS("branch-mispredicts",	"iap-br-inst-retired.mispred"),
649 	EV_ALIAS("cycles",		"tsc-tsc"),
650 	EV_ALIAS("ic-misses",		"iap-l1i-misses"),
651 	EV_ALIAS("instructions",	"iaf-instr-retired.any"),
652 	EV_ALIAS("interrupts",		"iap-hw-int-rcv"),
653 	EV_ALIAS("unhalted-cycles",	"iaf-cpu-clk-unhalted.core"),
654 	EV_ALIAS(NULL, NULL)
655 };
656 
657 static struct pmc_event_alias core2_aliases_without_iaf[] = {
658 	EV_ALIAS("branches",		"iap-br-inst-retired.any"),
659 	EV_ALIAS("branch-mispredicts",	"iap-br-inst-retired.mispred"),
660 	EV_ALIAS("cycles",		"tsc-tsc"),
661 	EV_ALIAS("ic-misses",		"iap-l1i-misses"),
662 	EV_ALIAS("instructions",	"iap-inst-retired.any_p"),
663 	EV_ALIAS("interrupts",		"iap-hw-int-rcv"),
664 	EV_ALIAS("unhalted-cycles",	"iap-cpu-clk-unhalted.core_p"),
665 	EV_ALIAS(NULL, NULL)
666 };
667 
668 #define	atom_aliases			core2_aliases
669 #define	atom_aliases_without_iaf	core2_aliases_without_iaf
670 #define	atom_silvermont_aliases		core2_aliases
671 #define	atom_silvermont_aliases_without_iaf	core2_aliases_without_iaf
672 #define corei7_aliases			core2_aliases
673 #define corei7_aliases_without_iaf	core2_aliases_without_iaf
674 #define nehalem_ex_aliases		core2_aliases
675 #define nehalem_ex_aliases_without_iaf	core2_aliases_without_iaf
676 #define haswell_aliases			core2_aliases
677 #define haswell_aliases_without_iaf	core2_aliases_without_iaf
678 #define haswell_xeon_aliases			core2_aliases
679 #define haswell_xeon_aliases_without_iaf	core2_aliases_without_iaf
680 #define ivybridge_aliases		core2_aliases
681 #define ivybridge_aliases_without_iaf	core2_aliases_without_iaf
682 #define ivybridge_xeon_aliases		core2_aliases
683 #define ivybridge_xeon_aliases_without_iaf	core2_aliases_without_iaf
684 #define sandybridge_aliases		core2_aliases
685 #define sandybridge_aliases_without_iaf	core2_aliases_without_iaf
686 #define sandybridge_xeon_aliases	core2_aliases
687 #define sandybridge_xeon_aliases_without_iaf	core2_aliases_without_iaf
688 #define westmere_aliases		core2_aliases
689 #define westmere_aliases_without_iaf	core2_aliases_without_iaf
690 #define westmere_ex_aliases		core2_aliases
691 #define westmere_ex_aliases_without_iaf	core2_aliases_without_iaf
692 
693 #define	IAF_KW_OS		"os"
694 #define	IAF_KW_USR		"usr"
695 #define	IAF_KW_ANYTHREAD	"anythread"
696 
697 /*
698  * Parse an event specifier for Intel fixed function counters.
699  */
700 static int
701 iaf_allocate_pmc(enum pmc_event pe, char *ctrspec,
702     struct pmc_op_pmcallocate *pmc_config)
703 {
704 	char *p;
705 
706 	(void) pe;
707 
708 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
709 	pmc_config->pm_md.pm_iaf.pm_iaf_flags = 0;
710 
711 	while ((p = strsep(&ctrspec, ",")) != NULL) {
712 		if (KWMATCH(p, IAF_KW_OS))
713 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
714 		else if (KWMATCH(p, IAF_KW_USR))
715 			pmc_config->pm_caps |= PMC_CAP_USER;
716 		else if (KWMATCH(p, IAF_KW_ANYTHREAD))
717 			pmc_config->pm_md.pm_iaf.pm_iaf_flags |= IAF_ANY;
718 		else
719 			return (-1);
720 	}
721 
722 	return (0);
723 }
724 
725 /*
726  * Core/Core2 support.
727  */
728 
729 #define	IAP_KW_AGENT		"agent"
730 #define	IAP_KW_ANYTHREAD	"anythread"
731 #define	IAP_KW_CACHESTATE	"cachestate"
732 #define	IAP_KW_CMASK		"cmask"
733 #define	IAP_KW_CORE		"core"
734 #define	IAP_KW_EDGE		"edge"
735 #define	IAP_KW_INV		"inv"
736 #define	IAP_KW_OS		"os"
737 #define	IAP_KW_PREFETCH		"prefetch"
738 #define	IAP_KW_SNOOPRESPONSE	"snoopresponse"
739 #define	IAP_KW_SNOOPTYPE	"snooptype"
740 #define	IAP_KW_TRANSITION	"trans"
741 #define	IAP_KW_USR		"usr"
742 #define	IAP_KW_RSP		"rsp"
743 
744 static struct pmc_masks iap_core_mask[] = {
745 	PMCMASK(all,	(0x3 << 14)),
746 	PMCMASK(this,	(0x1 << 14)),
747 	NULLMASK
748 };
749 
750 static struct pmc_masks iap_agent_mask[] = {
751 	PMCMASK(this,	0),
752 	PMCMASK(any,	(0x1 << 13)),
753 	NULLMASK
754 };
755 
756 static struct pmc_masks iap_prefetch_mask[] = {
757 	PMCMASK(both,		(0x3 << 12)),
758 	PMCMASK(only,		(0x1 << 12)),
759 	PMCMASK(exclude,	0),
760 	NULLMASK
761 };
762 
763 static struct pmc_masks iap_cachestate_mask[] = {
764 	PMCMASK(i,		(1 <<  8)),
765 	PMCMASK(s,		(1 <<  9)),
766 	PMCMASK(e,		(1 << 10)),
767 	PMCMASK(m,		(1 << 11)),
768 	NULLMASK
769 };
770 
771 static struct pmc_masks iap_snoopresponse_mask[] = {
772 	PMCMASK(clean,		(1 << 8)),
773 	PMCMASK(hit,		(1 << 9)),
774 	PMCMASK(hitm,		(1 << 11)),
775 	NULLMASK
776 };
777 
778 static struct pmc_masks iap_snooptype_mask[] = {
779 	PMCMASK(cmp2s,		(1 << 8)),
780 	PMCMASK(cmp2i,		(1 << 9)),
781 	NULLMASK
782 };
783 
784 static struct pmc_masks iap_transition_mask[] = {
785 	PMCMASK(any,		0x00),
786 	PMCMASK(frequency,	0x10),
787 	NULLMASK
788 };
789 
790 static struct pmc_masks iap_rsp_mask_i7_wm[] = {
791 	PMCMASK(DMND_DATA_RD,		(1 <<  0)),
792 	PMCMASK(DMND_RFO,		(1 <<  1)),
793 	PMCMASK(DMND_IFETCH,		(1 <<  2)),
794 	PMCMASK(WB,			(1 <<  3)),
795 	PMCMASK(PF_DATA_RD,		(1 <<  4)),
796 	PMCMASK(PF_RFO,			(1 <<  5)),
797 	PMCMASK(PF_IFETCH,		(1 <<  6)),
798 	PMCMASK(OTHER,			(1 <<  7)),
799 	PMCMASK(UNCORE_HIT,		(1 <<  8)),
800 	PMCMASK(OTHER_CORE_HIT_SNP,	(1 <<  9)),
801 	PMCMASK(OTHER_CORE_HITM,	(1 << 10)),
802 	PMCMASK(REMOTE_CACHE_FWD,	(1 << 12)),
803 	PMCMASK(REMOTE_DRAM,		(1 << 13)),
804 	PMCMASK(LOCAL_DRAM,		(1 << 14)),
805 	PMCMASK(NON_DRAM,		(1 << 15)),
806 	NULLMASK
807 };
808 
809 static struct pmc_masks iap_rsp_mask_sb_sbx_ib[] = {
810 	PMCMASK(REQ_DMND_DATA_RD,	(1ULL <<  0)),
811 	PMCMASK(REQ_DMND_RFO,		(1ULL <<  1)),
812 	PMCMASK(REQ_DMND_IFETCH,	(1ULL <<  2)),
813 	PMCMASK(REQ_WB,			(1ULL <<  3)),
814 	PMCMASK(REQ_PF_DATA_RD,		(1ULL <<  4)),
815 	PMCMASK(REQ_PF_RFO,		(1ULL <<  5)),
816 	PMCMASK(REQ_PF_IFETCH,		(1ULL <<  6)),
817 	PMCMASK(REQ_PF_LLC_DATA_RD,	(1ULL <<  7)),
818 	PMCMASK(REQ_PF_LLC_RFO,		(1ULL <<  8)),
819 	PMCMASK(REQ_PF_LLC_IFETCH,	(1ULL <<  9)),
820 	PMCMASK(REQ_BUS_LOCKS,		(1ULL << 10)),
821 	PMCMASK(REQ_STRM_ST,		(1ULL << 11)),
822 	PMCMASK(REQ_OTHER,		(1ULL << 15)),
823 	PMCMASK(RES_ANY,		(1ULL << 16)),
824 	PMCMASK(RES_SUPPLIER_SUPP,	(1ULL << 17)),
825 	PMCMASK(RES_SUPPLIER_LLC_HITM,	(1ULL << 18)),
826 	PMCMASK(RES_SUPPLIER_LLC_HITE,	(1ULL << 19)),
827 	PMCMASK(RES_SUPPLIER_LLC_HITS,	(1ULL << 20)),
828 	PMCMASK(RES_SUPPLIER_LLC_HITF,	(1ULL << 21)),
829 	PMCMASK(RES_SUPPLIER_LOCAL,	(1ULL << 22)),
830 	PMCMASK(RES_SNOOP_SNP_NONE,	(1ULL << 31)),
831 	PMCMASK(RES_SNOOP_SNP_NO_NEEDED,(1ULL << 32)),
832 	PMCMASK(RES_SNOOP_SNP_MISS,	(1ULL << 33)),
833 	PMCMASK(RES_SNOOP_HIT_NO_FWD,	(1ULL << 34)),
834 	PMCMASK(RES_SNOOP_HIT_FWD,	(1ULL << 35)),
835 	PMCMASK(RES_SNOOP_HITM,		(1ULL << 36)),
836 	PMCMASK(RES_NON_DRAM,		(1ULL << 37)),
837 	NULLMASK
838 };
839 
840 static struct pmc_masks iap_rsp_mask_haswell[] = {
841 	PMCMASK(REQ_DMND_DATA_RD,	(1ULL <<  0)),
842 	PMCMASK(REQ_DMND_RFO,		(1ULL <<  1)),
843 	PMCMASK(REQ_DMND_IFETCH,	(1ULL <<  2)),
844 	PMCMASK(REQ_PF_DATA_RD,		(1ULL <<  4)),
845 	PMCMASK(REQ_PF_RFO,		(1ULL <<  5)),
846 	PMCMASK(REQ_PF_IFETCH,		(1ULL <<  6)),
847 	PMCMASK(REQ_OTHER,		(1ULL << 15)),
848 	PMCMASK(RES_ANY,		(1ULL << 16)),
849 	PMCMASK(RES_SUPPLIER_SUPP,	(1ULL << 17)),
850 	PMCMASK(RES_SUPPLIER_LLC_HITM,	(1ULL << 18)),
851 	PMCMASK(RES_SUPPLIER_LLC_HITE,	(1ULL << 19)),
852 	PMCMASK(RES_SUPPLIER_LLC_HITS,	(1ULL << 20)),
853 	PMCMASK(RES_SUPPLIER_LLC_HITF,	(1ULL << 21)),
854 	PMCMASK(RES_SUPPLIER_LOCAL,	(1ULL << 22)),
855 	PMCMASK(RES_SNOOP_SNP_NONE,	(1ULL << 31)),
856 	PMCMASK(RES_SNOOP_SNP_NO_NEEDED,(1ULL << 32)),
857 	PMCMASK(RES_SNOOP_SNP_MISS,	(1ULL << 33)),
858 	PMCMASK(RES_SNOOP_HIT_NO_FWD,	(1ULL << 34)),
859 	PMCMASK(RES_SNOOP_HIT_FWD,	(1ULL << 35)),
860 	PMCMASK(RES_SNOOP_HITM,		(1ULL << 36)),
861 	PMCMASK(RES_NON_DRAM,		(1ULL << 37)),
862 	NULLMASK
863 };
864 
865 static int
866 iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
867     struct pmc_op_pmcallocate *pmc_config)
868 {
869 	char *e, *p, *q;
870 	uint64_t cachestate, evmask, rsp;
871 	int count, n;
872 
873 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE |
874 	    PMC_CAP_QUALIFIER);
875 	pmc_config->pm_md.pm_iap.pm_iap_config = 0;
876 
877 	cachestate = evmask = rsp = 0;
878 
879 	/* Parse additional modifiers if present */
880 	while ((p = strsep(&ctrspec, ",")) != NULL) {
881 
882 		n = 0;
883 		if (KWPREFIXMATCH(p, IAP_KW_CMASK "=")) {
884 			q = strchr(p, '=');
885 			if (*++q == '\0') /* skip '=' */
886 				return (-1);
887 			count = strtol(q, &e, 0);
888 			if (e == q || *e != '\0')
889 				return (-1);
890 			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
891 			pmc_config->pm_md.pm_iap.pm_iap_config |=
892 			    IAP_CMASK(count);
893 		} else if (KWMATCH(p, IAP_KW_EDGE)) {
894 			pmc_config->pm_caps |= PMC_CAP_EDGE;
895 		} else if (KWMATCH(p, IAP_KW_INV)) {
896 			pmc_config->pm_caps |= PMC_CAP_INVERT;
897 		} else if (KWMATCH(p, IAP_KW_OS)) {
898 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
899 		} else if (KWMATCH(p, IAP_KW_USR)) {
900 			pmc_config->pm_caps |= PMC_CAP_USER;
901 		} else if (KWMATCH(p, IAP_KW_ANYTHREAD)) {
902 			pmc_config->pm_md.pm_iap.pm_iap_config |= IAP_ANY;
903 		} else if (KWPREFIXMATCH(p, IAP_KW_CORE "=")) {
904 			n = pmc_parse_mask(iap_core_mask, p, &evmask);
905 			if (n != 1)
906 				return (-1);
907 		} else if (KWPREFIXMATCH(p, IAP_KW_AGENT "=")) {
908 			n = pmc_parse_mask(iap_agent_mask, p, &evmask);
909 			if (n != 1)
910 				return (-1);
911 		} else if (KWPREFIXMATCH(p, IAP_KW_PREFETCH "=")) {
912 			n = pmc_parse_mask(iap_prefetch_mask, p, &evmask);
913 			if (n != 1)
914 				return (-1);
915 		} else if (KWPREFIXMATCH(p, IAP_KW_CACHESTATE "=")) {
916 			n = pmc_parse_mask(iap_cachestate_mask, p, &cachestate);
917 		} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_CORE &&
918 		    KWPREFIXMATCH(p, IAP_KW_TRANSITION "=")) {
919 			n = pmc_parse_mask(iap_transition_mask, p, &evmask);
920 			if (n != 1)
921 				return (-1);
922 		} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_ATOM ||
923 		    cpu_info.pm_cputype == PMC_CPU_INTEL_ATOM_SILVERMONT ||
924 		    cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2 ||
925 		    cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2EXTREME) {
926 			if (KWPREFIXMATCH(p, IAP_KW_SNOOPRESPONSE "=")) {
927 				n = pmc_parse_mask(iap_snoopresponse_mask, p,
928 				    &evmask);
929 			} else if (KWPREFIXMATCH(p, IAP_KW_SNOOPTYPE "=")) {
930 				n = pmc_parse_mask(iap_snooptype_mask, p,
931 				    &evmask);
932 			} else
933 				return (-1);
934 		} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_COREI7 ||
935 		    cpu_info.pm_cputype == PMC_CPU_INTEL_WESTMERE ||
936 		    cpu_info.pm_cputype == PMC_CPU_INTEL_NEHALEM_EX ||
937 		    cpu_info.pm_cputype == PMC_CPU_INTEL_WESTMERE_EX) {
938 			if (KWPREFIXMATCH(p, IAP_KW_RSP "=")) {
939 				n = pmc_parse_mask(iap_rsp_mask_i7_wm, p, &rsp);
940 			} else
941 				return (-1);
942 		} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_SANDYBRIDGE ||
943 		    cpu_info.pm_cputype == PMC_CPU_INTEL_SANDYBRIDGE_XEON ||
944 			cpu_info.pm_cputype == PMC_CPU_INTEL_IVYBRIDGE ||
945 			cpu_info.pm_cputype == PMC_CPU_INTEL_IVYBRIDGE_XEON ) {
946 			if (KWPREFIXMATCH(p, IAP_KW_RSP "=")) {
947 				n = pmc_parse_mask(iap_rsp_mask_sb_sbx_ib, p, &rsp);
948 			} else
949 				return (-1);
950 		} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_HASWELL ||
951 			cpu_info.pm_cputype == PMC_CPU_INTEL_HASWELL_XEON) {
952 			if (KWPREFIXMATCH(p, IAP_KW_RSP "=")) {
953 				n = pmc_parse_mask(iap_rsp_mask_haswell, p, &rsp);
954 			} else
955 				return (-1);
956 		} else
957 			return (-1);
958 
959 		if (n < 0)	/* Parsing failed. */
960 			return (-1);
961 	}
962 
963 	pmc_config->pm_md.pm_iap.pm_iap_config |= evmask;
964 
965 	/*
966 	 * If the event requires a 'cachestate' qualifier but was not
967 	 * specified by the user, use a sensible default.
968 	 */
969 	switch (pe) {
970 	case PMC_EV_IAP_EVENT_28H: /* Core, Core2, Atom */
971 	case PMC_EV_IAP_EVENT_29H: /* Core, Core2, Atom */
972 	case PMC_EV_IAP_EVENT_2AH: /* Core, Core2, Atom */
973 	case PMC_EV_IAP_EVENT_2BH: /* Atom, Core2 */
974 	case PMC_EV_IAP_EVENT_2EH: /* Core, Core2, Atom */
975 	case PMC_EV_IAP_EVENT_30H: /* Core, Core2, Atom */
976 	case PMC_EV_IAP_EVENT_32H: /* Core */
977 	case PMC_EV_IAP_EVENT_40H: /* Core */
978 	case PMC_EV_IAP_EVENT_41H: /* Core */
979 	case PMC_EV_IAP_EVENT_42H: /* Core, Core2, Atom */
980 		if (cachestate == 0)
981 			cachestate = (0xF << 8);
982 		break;
983 	case PMC_EV_IAP_EVENT_77H: /* Atom */
984 		/* IAP_EVENT_77H only accepts a cachestate qualifier on the
985 		 * Atom processor
986 		 */
987 		if(cpu_info.pm_cputype == PMC_CPU_INTEL_ATOM && cachestate == 0)
988 			cachestate = (0xF << 8);
989 	    break;
990 	default:
991 		break;
992 	}
993 
994 	pmc_config->pm_md.pm_iap.pm_iap_config |= cachestate;
995 	pmc_config->pm_md.pm_iap.pm_iap_rsp = rsp;
996 
997 	return (0);
998 }
999 
1000 /*
1001  * Intel Uncore.
1002  */
1003 
1004 static int
1005 ucf_allocate_pmc(enum pmc_event pe, char *ctrspec,
1006     struct pmc_op_pmcallocate *pmc_config)
1007 {
1008 	(void) pe;
1009 	(void) ctrspec;
1010 
1011 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
1012 	pmc_config->pm_md.pm_ucf.pm_ucf_flags = 0;
1013 
1014 	return (0);
1015 }
1016 
1017 #define	UCP_KW_CMASK		"cmask"
1018 #define	UCP_KW_EDGE		"edge"
1019 #define	UCP_KW_INV		"inv"
1020 
1021 static int
1022 ucp_allocate_pmc(enum pmc_event pe, char *ctrspec,
1023     struct pmc_op_pmcallocate *pmc_config)
1024 {
1025 	char *e, *p, *q;
1026 	int count, n;
1027 
1028 	(void) pe;
1029 
1030 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE |
1031 	    PMC_CAP_QUALIFIER);
1032 	pmc_config->pm_md.pm_ucp.pm_ucp_config = 0;
1033 
1034 	/* Parse additional modifiers if present */
1035 	while ((p = strsep(&ctrspec, ",")) != NULL) {
1036 
1037 		n = 0;
1038 		if (KWPREFIXMATCH(p, UCP_KW_CMASK "=")) {
1039 			q = strchr(p, '=');
1040 			if (*++q == '\0') /* skip '=' */
1041 				return (-1);
1042 			count = strtol(q, &e, 0);
1043 			if (e == q || *e != '\0')
1044 				return (-1);
1045 			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
1046 			pmc_config->pm_md.pm_ucp.pm_ucp_config |=
1047 			    UCP_CMASK(count);
1048 		} else if (KWMATCH(p, UCP_KW_EDGE)) {
1049 			pmc_config->pm_caps |= PMC_CAP_EDGE;
1050 		} else if (KWMATCH(p, UCP_KW_INV)) {
1051 			pmc_config->pm_caps |= PMC_CAP_INVERT;
1052 		} else
1053 			return (-1);
1054 
1055 		if (n < 0)	/* Parsing failed. */
1056 			return (-1);
1057 	}
1058 
1059 	return (0);
1060 }
1061 
1062 /*
1063  * AMD K8 PMCs.
1064  *
1065  * These are very similar to AMD K7 PMCs, but support more kinds of
1066  * events.
1067  */
1068 
1069 static struct pmc_event_alias k8_aliases[] = {
1070 	EV_ALIAS("branches",		"k8-fr-retired-taken-branches"),
1071 	EV_ALIAS("branch-mispredicts",
1072 	    "k8-fr-retired-taken-branches-mispredicted"),
1073 	EV_ALIAS("cycles",		"tsc"),
1074 	EV_ALIAS("dc-misses",		"k8-dc-miss"),
1075 	EV_ALIAS("ic-misses",		"k8-ic-miss"),
1076 	EV_ALIAS("instructions",	"k8-fr-retired-x86-instructions"),
1077 	EV_ALIAS("interrupts",		"k8-fr-taken-hardware-interrupts"),
1078 	EV_ALIAS("unhalted-cycles",	"k8-bu-cpu-clk-unhalted"),
1079 	EV_ALIAS(NULL, NULL)
1080 };
1081 
1082 #define	__K8MASK(N,V) PMCMASK(N,(1 << (V)))
1083 
1084 /*
1085  * Parsing tables
1086  */
1087 
1088 /* fp dispatched fpu ops */
1089 static const struct pmc_masks k8_mask_fdfo[] = {
1090 	__K8MASK(add-pipe-excluding-junk-ops,	0),
1091 	__K8MASK(multiply-pipe-excluding-junk-ops,	1),
1092 	__K8MASK(store-pipe-excluding-junk-ops,	2),
1093 	__K8MASK(add-pipe-junk-ops,		3),
1094 	__K8MASK(multiply-pipe-junk-ops,	4),
1095 	__K8MASK(store-pipe-junk-ops,		5),
1096 	NULLMASK
1097 };
1098 
1099 /* ls segment register loads */
1100 static const struct pmc_masks k8_mask_lsrl[] = {
1101 	__K8MASK(es,	0),
1102 	__K8MASK(cs,	1),
1103 	__K8MASK(ss,	2),
1104 	__K8MASK(ds,	3),
1105 	__K8MASK(fs,	4),
1106 	__K8MASK(gs,	5),
1107 	__K8MASK(hs,	6),
1108 	NULLMASK
1109 };
1110 
1111 /* ls locked operation */
1112 static const struct pmc_masks k8_mask_llo[] = {
1113 	__K8MASK(locked-instructions,	0),
1114 	__K8MASK(cycles-in-request,	1),
1115 	__K8MASK(cycles-to-complete,	2),
1116 	NULLMASK
1117 };
1118 
1119 /* dc refill from {l2,system} and dc copyback */
1120 static const struct pmc_masks k8_mask_dc[] = {
1121 	__K8MASK(invalid,	0),
1122 	__K8MASK(shared,	1),
1123 	__K8MASK(exclusive,	2),
1124 	__K8MASK(owner,		3),
1125 	__K8MASK(modified,	4),
1126 	NULLMASK
1127 };
1128 
1129 /* dc one bit ecc error */
1130 static const struct pmc_masks k8_mask_dobee[] = {
1131 	__K8MASK(scrubber,	0),
1132 	__K8MASK(piggyback,	1),
1133 	NULLMASK
1134 };
1135 
1136 /* dc dispatched prefetch instructions */
1137 static const struct pmc_masks k8_mask_ddpi[] = {
1138 	__K8MASK(load,	0),
1139 	__K8MASK(store,	1),
1140 	__K8MASK(nta,	2),
1141 	NULLMASK
1142 };
1143 
1144 /* dc dcache accesses by locks */
1145 static const struct pmc_masks k8_mask_dabl[] = {
1146 	__K8MASK(accesses,	0),
1147 	__K8MASK(misses,	1),
1148 	NULLMASK
1149 };
1150 
1151 /* bu internal l2 request */
1152 static const struct pmc_masks k8_mask_bilr[] = {
1153 	__K8MASK(ic-fill,	0),
1154 	__K8MASK(dc-fill,	1),
1155 	__K8MASK(tlb-reload,	2),
1156 	__K8MASK(tag-snoop,	3),
1157 	__K8MASK(cancelled,	4),
1158 	NULLMASK
1159 };
1160 
1161 /* bu fill request l2 miss */
1162 static const struct pmc_masks k8_mask_bfrlm[] = {
1163 	__K8MASK(ic-fill,	0),
1164 	__K8MASK(dc-fill,	1),
1165 	__K8MASK(tlb-reload,	2),
1166 	NULLMASK
1167 };
1168 
1169 /* bu fill into l2 */
1170 static const struct pmc_masks k8_mask_bfil[] = {
1171 	__K8MASK(dirty-l2-victim,	0),
1172 	__K8MASK(victim-from-l2,	1),
1173 	NULLMASK
1174 };
1175 
1176 /* fr retired fpu instructions */
1177 static const struct pmc_masks k8_mask_frfi[] = {
1178 	__K8MASK(x87,			0),
1179 	__K8MASK(mmx-3dnow,		1),
1180 	__K8MASK(packed-sse-sse2,	2),
1181 	__K8MASK(scalar-sse-sse2,	3),
1182 	NULLMASK
1183 };
1184 
1185 /* fr retired fastpath double op instructions */
1186 static const struct pmc_masks k8_mask_frfdoi[] = {
1187 	__K8MASK(low-op-pos-0,		0),
1188 	__K8MASK(low-op-pos-1,		1),
1189 	__K8MASK(low-op-pos-2,		2),
1190 	NULLMASK
1191 };
1192 
1193 /* fr fpu exceptions */
1194 static const struct pmc_masks k8_mask_ffe[] = {
1195 	__K8MASK(x87-reclass-microfaults,	0),
1196 	__K8MASK(sse-retype-microfaults,	1),
1197 	__K8MASK(sse-reclass-microfaults,	2),
1198 	__K8MASK(sse-and-x87-microtraps,	3),
1199 	NULLMASK
1200 };
1201 
1202 /* nb memory controller page access event */
1203 static const struct pmc_masks k8_mask_nmcpae[] = {
1204 	__K8MASK(page-hit,	0),
1205 	__K8MASK(page-miss,	1),
1206 	__K8MASK(page-conflict,	2),
1207 	NULLMASK
1208 };
1209 
1210 /* nb memory controller turnaround */
1211 static const struct pmc_masks k8_mask_nmct[] = {
1212 	__K8MASK(dimm-turnaround,		0),
1213 	__K8MASK(read-to-write-turnaround,	1),
1214 	__K8MASK(write-to-read-turnaround,	2),
1215 	NULLMASK
1216 };
1217 
1218 /* nb memory controller bypass saturation */
1219 static const struct pmc_masks k8_mask_nmcbs[] = {
1220 	__K8MASK(memory-controller-hi-pri-bypass,	0),
1221 	__K8MASK(memory-controller-lo-pri-bypass,	1),
1222 	__K8MASK(dram-controller-interface-bypass,	2),
1223 	__K8MASK(dram-controller-queue-bypass,		3),
1224 	NULLMASK
1225 };
1226 
1227 /* nb sized commands */
1228 static const struct pmc_masks k8_mask_nsc[] = {
1229 	__K8MASK(nonpostwrszbyte,	0),
1230 	__K8MASK(nonpostwrszdword,	1),
1231 	__K8MASK(postwrszbyte,		2),
1232 	__K8MASK(postwrszdword,		3),
1233 	__K8MASK(rdszbyte,		4),
1234 	__K8MASK(rdszdword,		5),
1235 	__K8MASK(rdmodwr,		6),
1236 	NULLMASK
1237 };
1238 
1239 /* nb probe result */
1240 static const struct pmc_masks k8_mask_npr[] = {
1241 	__K8MASK(probe-miss,		0),
1242 	__K8MASK(probe-hit,		1),
1243 	__K8MASK(probe-hit-dirty-no-memory-cancel, 2),
1244 	__K8MASK(probe-hit-dirty-with-memory-cancel, 3),
1245 	NULLMASK
1246 };
1247 
1248 /* nb hypertransport bus bandwidth */
1249 static const struct pmc_masks k8_mask_nhbb[] = { /* HT bus bandwidth */
1250 	__K8MASK(command,	0),
1251 	__K8MASK(data,	1),
1252 	__K8MASK(buffer-release, 2),
1253 	__K8MASK(nop,	3),
1254 	NULLMASK
1255 };
1256 
1257 #undef	__K8MASK
1258 
1259 #define	K8_KW_COUNT	"count"
1260 #define	K8_KW_EDGE	"edge"
1261 #define	K8_KW_INV	"inv"
1262 #define	K8_KW_MASK	"mask"
1263 #define	K8_KW_OS	"os"
1264 #define	K8_KW_USR	"usr"
1265 
1266 static int
1267 k8_allocate_pmc(enum pmc_event pe, char *ctrspec,
1268     struct pmc_op_pmcallocate *pmc_config)
1269 {
1270 	char		*e, *p, *q;
1271 	int		n;
1272 	uint32_t	count;
1273 	uint64_t	evmask;
1274 	const struct pmc_masks	*pm, *pmask;
1275 
1276 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
1277 	pmc_config->pm_md.pm_amd.pm_amd_config = 0;
1278 
1279 	pmask = NULL;
1280 	evmask = 0;
1281 
1282 #define	__K8SETMASK(M) pmask = k8_mask_##M
1283 
1284 	/* setup parsing tables */
1285 	switch (pe) {
1286 	case PMC_EV_K8_FP_DISPATCHED_FPU_OPS:
1287 		__K8SETMASK(fdfo);
1288 		break;
1289 	case PMC_EV_K8_LS_SEGMENT_REGISTER_LOAD:
1290 		__K8SETMASK(lsrl);
1291 		break;
1292 	case PMC_EV_K8_LS_LOCKED_OPERATION:
1293 		__K8SETMASK(llo);
1294 		break;
1295 	case PMC_EV_K8_DC_REFILL_FROM_L2:
1296 	case PMC_EV_K8_DC_REFILL_FROM_SYSTEM:
1297 	case PMC_EV_K8_DC_COPYBACK:
1298 		__K8SETMASK(dc);
1299 		break;
1300 	case PMC_EV_K8_DC_ONE_BIT_ECC_ERROR:
1301 		__K8SETMASK(dobee);
1302 		break;
1303 	case PMC_EV_K8_DC_DISPATCHED_PREFETCH_INSTRUCTIONS:
1304 		__K8SETMASK(ddpi);
1305 		break;
1306 	case PMC_EV_K8_DC_DCACHE_ACCESSES_BY_LOCKS:
1307 		__K8SETMASK(dabl);
1308 		break;
1309 	case PMC_EV_K8_BU_INTERNAL_L2_REQUEST:
1310 		__K8SETMASK(bilr);
1311 		break;
1312 	case PMC_EV_K8_BU_FILL_REQUEST_L2_MISS:
1313 		__K8SETMASK(bfrlm);
1314 		break;
1315 	case PMC_EV_K8_BU_FILL_INTO_L2:
1316 		__K8SETMASK(bfil);
1317 		break;
1318 	case PMC_EV_K8_FR_RETIRED_FPU_INSTRUCTIONS:
1319 		__K8SETMASK(frfi);
1320 		break;
1321 	case PMC_EV_K8_FR_RETIRED_FASTPATH_DOUBLE_OP_INSTRUCTIONS:
1322 		__K8SETMASK(frfdoi);
1323 		break;
1324 	case PMC_EV_K8_FR_FPU_EXCEPTIONS:
1325 		__K8SETMASK(ffe);
1326 		break;
1327 	case PMC_EV_K8_NB_MEMORY_CONTROLLER_PAGE_ACCESS_EVENT:
1328 		__K8SETMASK(nmcpae);
1329 		break;
1330 	case PMC_EV_K8_NB_MEMORY_CONTROLLER_TURNAROUND:
1331 		__K8SETMASK(nmct);
1332 		break;
1333 	case PMC_EV_K8_NB_MEMORY_CONTROLLER_BYPASS_SATURATION:
1334 		__K8SETMASK(nmcbs);
1335 		break;
1336 	case PMC_EV_K8_NB_SIZED_COMMANDS:
1337 		__K8SETMASK(nsc);
1338 		break;
1339 	case PMC_EV_K8_NB_PROBE_RESULT:
1340 		__K8SETMASK(npr);
1341 		break;
1342 	case PMC_EV_K8_NB_HT_BUS0_BANDWIDTH:
1343 	case PMC_EV_K8_NB_HT_BUS1_BANDWIDTH:
1344 	case PMC_EV_K8_NB_HT_BUS2_BANDWIDTH:
1345 		__K8SETMASK(nhbb);
1346 		break;
1347 
1348 	default:
1349 		break;		/* no options defined */
1350 	}
1351 
1352 	while ((p = strsep(&ctrspec, ",")) != NULL) {
1353 		if (KWPREFIXMATCH(p, K8_KW_COUNT "=")) {
1354 			q = strchr(p, '=');
1355 			if (*++q == '\0') /* skip '=' */
1356 				return (-1);
1357 
1358 			count = strtol(q, &e, 0);
1359 			if (e == q || *e != '\0')
1360 				return (-1);
1361 
1362 			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
1363 			pmc_config->pm_md.pm_amd.pm_amd_config |=
1364 			    AMD_PMC_TO_COUNTER(count);
1365 
1366 		} else if (KWMATCH(p, K8_KW_EDGE)) {
1367 			pmc_config->pm_caps |= PMC_CAP_EDGE;
1368 		} else if (KWMATCH(p, K8_KW_INV)) {
1369 			pmc_config->pm_caps |= PMC_CAP_INVERT;
1370 		} else if (KWPREFIXMATCH(p, K8_KW_MASK "=")) {
1371 			if ((n = pmc_parse_mask(pmask, p, &evmask)) < 0)
1372 				return (-1);
1373 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
1374 		} else if (KWMATCH(p, K8_KW_OS)) {
1375 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
1376 		} else if (KWMATCH(p, K8_KW_USR)) {
1377 			pmc_config->pm_caps |= PMC_CAP_USER;
1378 		} else
1379 			return (-1);
1380 	}
1381 
1382 	/* other post processing */
1383 	switch (pe) {
1384 	case PMC_EV_K8_FP_DISPATCHED_FPU_OPS:
1385 	case PMC_EV_K8_FP_CYCLES_WITH_NO_FPU_OPS_RETIRED:
1386 	case PMC_EV_K8_FP_DISPATCHED_FPU_FAST_FLAG_OPS:
1387 	case PMC_EV_K8_FR_RETIRED_FASTPATH_DOUBLE_OP_INSTRUCTIONS:
1388 	case PMC_EV_K8_FR_RETIRED_FPU_INSTRUCTIONS:
1389 	case PMC_EV_K8_FR_FPU_EXCEPTIONS:
1390 		/* XXX only available in rev B and later */
1391 		break;
1392 	case PMC_EV_K8_DC_DCACHE_ACCESSES_BY_LOCKS:
1393 		/* XXX only available in rev C and later */
1394 		break;
1395 	case PMC_EV_K8_LS_LOCKED_OPERATION:
1396 		/* XXX CPU Rev A,B evmask is to be zero */
1397 		if (evmask & (evmask - 1)) /* > 1 bit set */
1398 			return (-1);
1399 		if (evmask == 0) {
1400 			evmask = 0x01; /* Rev C and later: #instrs */
1401 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
1402 		}
1403 		break;
1404 	default:
1405 		if (evmask == 0 && pmask != NULL) {
1406 			for (pm = pmask; pm->pm_name; pm++)
1407 				evmask |= pm->pm_value;
1408 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
1409 		}
1410 	}
1411 
1412 	if (pmc_config->pm_caps & PMC_CAP_QUALIFIER)
1413 		pmc_config->pm_md.pm_amd.pm_amd_config =
1414 		    AMD_PMC_TO_UNITMASK(evmask);
1415 
1416 	return (0);
1417 }
1418 
1419 #endif
1420 
1421 #if defined(__amd64__) || defined(__i386__)
1422 
1423 /*
1424  * Intel P4 PMCs
1425  */
1426 
1427 static struct pmc_event_alias p4_aliases[] = {
1428 	EV_ALIAS("branches",		"p4-branch-retired,mask=mmtp+mmtm"),
1429 	EV_ALIAS("branch-mispredicts",	"p4-mispred-branch-retired"),
1430 	EV_ALIAS("cycles",		"tsc"),
1431 	EV_ALIAS("instructions",
1432 	    "p4-instr-retired,mask=nbogusntag+nbogustag"),
1433 	EV_ALIAS("unhalted-cycles",	"p4-global-power-events"),
1434 	EV_ALIAS(NULL, NULL)
1435 };
1436 
1437 #define	P4_KW_ACTIVE	"active"
1438 #define	P4_KW_ACTIVE_ANY "any"
1439 #define	P4_KW_ACTIVE_BOTH "both"
1440 #define	P4_KW_ACTIVE_NONE "none"
1441 #define	P4_KW_ACTIVE_SINGLE "single"
1442 #define	P4_KW_BUSREQTYPE "busreqtype"
1443 #define	P4_KW_CASCADE	"cascade"
1444 #define	P4_KW_EDGE	"edge"
1445 #define	P4_KW_INV	"complement"
1446 #define	P4_KW_OS	"os"
1447 #define	P4_KW_MASK	"mask"
1448 #define	P4_KW_PRECISE	"precise"
1449 #define	P4_KW_TAG	"tag"
1450 #define	P4_KW_THRESHOLD	"threshold"
1451 #define	P4_KW_USR	"usr"
1452 
1453 #define	__P4MASK(N,V) PMCMASK(N, (1 << (V)))
1454 
1455 static const struct pmc_masks p4_mask_tcdm[] = { /* tc deliver mode */
1456 	__P4MASK(dd, 0),
1457 	__P4MASK(db, 1),
1458 	__P4MASK(di, 2),
1459 	__P4MASK(bd, 3),
1460 	__P4MASK(bb, 4),
1461 	__P4MASK(bi, 5),
1462 	__P4MASK(id, 6),
1463 	__P4MASK(ib, 7),
1464 	NULLMASK
1465 };
1466 
1467 static const struct pmc_masks p4_mask_bfr[] = { /* bpu fetch request */
1468 	__P4MASK(tcmiss, 0),
1469 	NULLMASK,
1470 };
1471 
1472 static const struct pmc_masks p4_mask_ir[] = { /* itlb reference */
1473 	__P4MASK(hit, 0),
1474 	__P4MASK(miss, 1),
1475 	__P4MASK(hit-uc, 2),
1476 	NULLMASK
1477 };
1478 
1479 static const struct pmc_masks p4_mask_memcan[] = { /* memory cancel */
1480 	__P4MASK(st-rb-full, 2),
1481 	__P4MASK(64k-conf, 3),
1482 	NULLMASK
1483 };
1484 
1485 static const struct pmc_masks p4_mask_memcomp[] = { /* memory complete */
1486 	__P4MASK(lsc, 0),
1487 	__P4MASK(ssc, 1),
1488 	NULLMASK
1489 };
1490 
1491 static const struct pmc_masks p4_mask_lpr[] = { /* load port replay */
1492 	__P4MASK(split-ld, 1),
1493 	NULLMASK
1494 };
1495 
1496 static const struct pmc_masks p4_mask_spr[] = { /* store port replay */
1497 	__P4MASK(split-st, 1),
1498 	NULLMASK
1499 };
1500 
1501 static const struct pmc_masks p4_mask_mlr[] = { /* mob load replay */
1502 	__P4MASK(no-sta, 1),
1503 	__P4MASK(no-std, 3),
1504 	__P4MASK(partial-data, 4),
1505 	__P4MASK(unalgn-addr, 5),
1506 	NULLMASK
1507 };
1508 
1509 static const struct pmc_masks p4_mask_pwt[] = { /* page walk type */
1510 	__P4MASK(dtmiss, 0),
1511 	__P4MASK(itmiss, 1),
1512 	NULLMASK
1513 };
1514 
1515 static const struct pmc_masks p4_mask_bcr[] = { /* bsq cache reference */
1516 	__P4MASK(rd-2ndl-hits, 0),
1517 	__P4MASK(rd-2ndl-hite, 1),
1518 	__P4MASK(rd-2ndl-hitm, 2),
1519 	__P4MASK(rd-3rdl-hits, 3),
1520 	__P4MASK(rd-3rdl-hite, 4),
1521 	__P4MASK(rd-3rdl-hitm, 5),
1522 	__P4MASK(rd-2ndl-miss, 8),
1523 	__P4MASK(rd-3rdl-miss, 9),
1524 	__P4MASK(wr-2ndl-miss, 10),
1525 	NULLMASK
1526 };
1527 
1528 static const struct pmc_masks p4_mask_ia[] = { /* ioq allocation */
1529 	__P4MASK(all-read, 5),
1530 	__P4MASK(all-write, 6),
1531 	__P4MASK(mem-uc, 7),
1532 	__P4MASK(mem-wc, 8),
1533 	__P4MASK(mem-wt, 9),
1534 	__P4MASK(mem-wp, 10),
1535 	__P4MASK(mem-wb, 11),
1536 	__P4MASK(own, 13),
1537 	__P4MASK(other, 14),
1538 	__P4MASK(prefetch, 15),
1539 	NULLMASK
1540 };
1541 
1542 static const struct pmc_masks p4_mask_iae[] = { /* ioq active entries */
1543 	__P4MASK(all-read, 5),
1544 	__P4MASK(all-write, 6),
1545 	__P4MASK(mem-uc, 7),
1546 	__P4MASK(mem-wc, 8),
1547 	__P4MASK(mem-wt, 9),
1548 	__P4MASK(mem-wp, 10),
1549 	__P4MASK(mem-wb, 11),
1550 	__P4MASK(own, 13),
1551 	__P4MASK(other, 14),
1552 	__P4MASK(prefetch, 15),
1553 	NULLMASK
1554 };
1555 
1556 static const struct pmc_masks p4_mask_fda[] = { /* fsb data activity */
1557 	__P4MASK(drdy-drv, 0),
1558 	__P4MASK(drdy-own, 1),
1559 	__P4MASK(drdy-other, 2),
1560 	__P4MASK(dbsy-drv, 3),
1561 	__P4MASK(dbsy-own, 4),
1562 	__P4MASK(dbsy-other, 5),
1563 	NULLMASK
1564 };
1565 
1566 static const struct pmc_masks p4_mask_ba[] = { /* bsq allocation */
1567 	__P4MASK(req-type0, 0),
1568 	__P4MASK(req-type1, 1),
1569 	__P4MASK(req-len0, 2),
1570 	__P4MASK(req-len1, 3),
1571 	__P4MASK(req-io-type, 5),
1572 	__P4MASK(req-lock-type, 6),
1573 	__P4MASK(req-cache-type, 7),
1574 	__P4MASK(req-split-type, 8),
1575 	__P4MASK(req-dem-type, 9),
1576 	__P4MASK(req-ord-type, 10),
1577 	__P4MASK(mem-type0, 11),
1578 	__P4MASK(mem-type1, 12),
1579 	__P4MASK(mem-type2, 13),
1580 	NULLMASK
1581 };
1582 
1583 static const struct pmc_masks p4_mask_sia[] = { /* sse input assist */
1584 	__P4MASK(all, 15),
1585 	NULLMASK
1586 };
1587 
1588 static const struct pmc_masks p4_mask_psu[] = { /* packed sp uop */
1589 	__P4MASK(all, 15),
1590 	NULLMASK
1591 };
1592 
1593 static const struct pmc_masks p4_mask_pdu[] = { /* packed dp uop */
1594 	__P4MASK(all, 15),
1595 	NULLMASK
1596 };
1597 
1598 static const struct pmc_masks p4_mask_ssu[] = { /* scalar sp uop */
1599 	__P4MASK(all, 15),
1600 	NULLMASK
1601 };
1602 
1603 static const struct pmc_masks p4_mask_sdu[] = { /* scalar dp uop */
1604 	__P4MASK(all, 15),
1605 	NULLMASK
1606 };
1607 
1608 static const struct pmc_masks p4_mask_64bmu[] = { /* 64 bit mmx uop */
1609 	__P4MASK(all, 15),
1610 	NULLMASK
1611 };
1612 
1613 static const struct pmc_masks p4_mask_128bmu[] = { /* 128 bit mmx uop */
1614 	__P4MASK(all, 15),
1615 	NULLMASK
1616 };
1617 
1618 static const struct pmc_masks p4_mask_xfu[] = { /* X87 fp uop */
1619 	__P4MASK(all, 15),
1620 	NULLMASK
1621 };
1622 
1623 static const struct pmc_masks p4_mask_xsmu[] = { /* x87 simd moves uop */
1624 	__P4MASK(allp0, 3),
1625 	__P4MASK(allp2, 4),
1626 	NULLMASK
1627 };
1628 
1629 static const struct pmc_masks p4_mask_gpe[] = { /* global power events */
1630 	__P4MASK(running, 0),
1631 	NULLMASK
1632 };
1633 
1634 static const struct pmc_masks p4_mask_tmx[] = { /* TC ms xfer */
1635 	__P4MASK(cisc, 0),
1636 	NULLMASK
1637 };
1638 
1639 static const struct pmc_masks p4_mask_uqw[] = { /* uop queue writes */
1640 	__P4MASK(from-tc-build, 0),
1641 	__P4MASK(from-tc-deliver, 1),
1642 	__P4MASK(from-rom, 2),
1643 	NULLMASK
1644 };
1645 
1646 static const struct pmc_masks p4_mask_rmbt[] = {
1647 	/* retired mispred branch type */
1648 	__P4MASK(conditional, 1),
1649 	__P4MASK(call, 2),
1650 	__P4MASK(return, 3),
1651 	__P4MASK(indirect, 4),
1652 	NULLMASK
1653 };
1654 
1655 static const struct pmc_masks p4_mask_rbt[] = { /* retired branch type */
1656 	__P4MASK(conditional, 1),
1657 	__P4MASK(call, 2),
1658 	__P4MASK(retired, 3),
1659 	__P4MASK(indirect, 4),
1660 	NULLMASK
1661 };
1662 
1663 static const struct pmc_masks p4_mask_rs[] = { /* resource stall */
1664 	__P4MASK(sbfull, 5),
1665 	NULLMASK
1666 };
1667 
1668 static const struct pmc_masks p4_mask_wb[] = { /* WC buffer */
1669 	__P4MASK(wcb-evicts, 0),
1670 	__P4MASK(wcb-full-evict, 1),
1671 	NULLMASK
1672 };
1673 
1674 static const struct pmc_masks p4_mask_fee[] = { /* front end event */
1675 	__P4MASK(nbogus, 0),
1676 	__P4MASK(bogus, 1),
1677 	NULLMASK
1678 };
1679 
1680 static const struct pmc_masks p4_mask_ee[] = { /* execution event */
1681 	__P4MASK(nbogus0, 0),
1682 	__P4MASK(nbogus1, 1),
1683 	__P4MASK(nbogus2, 2),
1684 	__P4MASK(nbogus3, 3),
1685 	__P4MASK(bogus0, 4),
1686 	__P4MASK(bogus1, 5),
1687 	__P4MASK(bogus2, 6),
1688 	__P4MASK(bogus3, 7),
1689 	NULLMASK
1690 };
1691 
1692 static const struct pmc_masks p4_mask_re[] = { /* replay event */
1693 	__P4MASK(nbogus, 0),
1694 	__P4MASK(bogus, 1),
1695 	NULLMASK
1696 };
1697 
1698 static const struct pmc_masks p4_mask_insret[] = { /* instr retired */
1699 	__P4MASK(nbogusntag, 0),
1700 	__P4MASK(nbogustag, 1),
1701 	__P4MASK(bogusntag, 2),
1702 	__P4MASK(bogustag, 3),
1703 	NULLMASK
1704 };
1705 
1706 static const struct pmc_masks p4_mask_ur[] = { /* uops retired */
1707 	__P4MASK(nbogus, 0),
1708 	__P4MASK(bogus, 1),
1709 	NULLMASK
1710 };
1711 
1712 static const struct pmc_masks p4_mask_ut[] = { /* uop type */
1713 	__P4MASK(tagloads, 1),
1714 	__P4MASK(tagstores, 2),
1715 	NULLMASK
1716 };
1717 
1718 static const struct pmc_masks p4_mask_br[] = { /* branch retired */
1719 	__P4MASK(mmnp, 0),
1720 	__P4MASK(mmnm, 1),
1721 	__P4MASK(mmtp, 2),
1722 	__P4MASK(mmtm, 3),
1723 	NULLMASK
1724 };
1725 
1726 static const struct pmc_masks p4_mask_mbr[] = { /* mispred branch retired */
1727 	__P4MASK(nbogus, 0),
1728 	NULLMASK
1729 };
1730 
1731 static const struct pmc_masks p4_mask_xa[] = { /* x87 assist */
1732 	__P4MASK(fpsu, 0),
1733 	__P4MASK(fpso, 1),
1734 	__P4MASK(poao, 2),
1735 	__P4MASK(poau, 3),
1736 	__P4MASK(prea, 4),
1737 	NULLMASK
1738 };
1739 
1740 static const struct pmc_masks p4_mask_machclr[] = { /* machine clear */
1741 	__P4MASK(clear, 0),
1742 	__P4MASK(moclear, 2),
1743 	__P4MASK(smclear, 3),
1744 	NULLMASK
1745 };
1746 
1747 /* P4 event parser */
1748 static int
1749 p4_allocate_pmc(enum pmc_event pe, char *ctrspec,
1750     struct pmc_op_pmcallocate *pmc_config)
1751 {
1752 
1753 	char	*e, *p, *q;
1754 	int	count, has_tag, has_busreqtype, n;
1755 	uint32_t cccractivemask;
1756 	uint64_t evmask;
1757 	const struct pmc_masks *pm, *pmask;
1758 
1759 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
1760 	pmc_config->pm_md.pm_p4.pm_p4_cccrconfig =
1761 	    pmc_config->pm_md.pm_p4.pm_p4_escrconfig = 0;
1762 
1763 	pmask   = NULL;
1764 	evmask  = 0;
1765 	cccractivemask = 0x3;
1766 	has_tag = has_busreqtype = 0;
1767 
1768 #define	__P4SETMASK(M) do {				\
1769 	pmask = p4_mask_##M;				\
1770 } while (0)
1771 
1772 	switch (pe) {
1773 	case PMC_EV_P4_TC_DELIVER_MODE:
1774 		__P4SETMASK(tcdm);
1775 		break;
1776 	case PMC_EV_P4_BPU_FETCH_REQUEST:
1777 		__P4SETMASK(bfr);
1778 		break;
1779 	case PMC_EV_P4_ITLB_REFERENCE:
1780 		__P4SETMASK(ir);
1781 		break;
1782 	case PMC_EV_P4_MEMORY_CANCEL:
1783 		__P4SETMASK(memcan);
1784 		break;
1785 	case PMC_EV_P4_MEMORY_COMPLETE:
1786 		__P4SETMASK(memcomp);
1787 		break;
1788 	case PMC_EV_P4_LOAD_PORT_REPLAY:
1789 		__P4SETMASK(lpr);
1790 		break;
1791 	case PMC_EV_P4_STORE_PORT_REPLAY:
1792 		__P4SETMASK(spr);
1793 		break;
1794 	case PMC_EV_P4_MOB_LOAD_REPLAY:
1795 		__P4SETMASK(mlr);
1796 		break;
1797 	case PMC_EV_P4_PAGE_WALK_TYPE:
1798 		__P4SETMASK(pwt);
1799 		break;
1800 	case PMC_EV_P4_BSQ_CACHE_REFERENCE:
1801 		__P4SETMASK(bcr);
1802 		break;
1803 	case PMC_EV_P4_IOQ_ALLOCATION:
1804 		__P4SETMASK(ia);
1805 		has_busreqtype = 1;
1806 		break;
1807 	case PMC_EV_P4_IOQ_ACTIVE_ENTRIES:
1808 		__P4SETMASK(iae);
1809 		has_busreqtype = 1;
1810 		break;
1811 	case PMC_EV_P4_FSB_DATA_ACTIVITY:
1812 		__P4SETMASK(fda);
1813 		break;
1814 	case PMC_EV_P4_BSQ_ALLOCATION:
1815 		__P4SETMASK(ba);
1816 		break;
1817 	case PMC_EV_P4_SSE_INPUT_ASSIST:
1818 		__P4SETMASK(sia);
1819 		break;
1820 	case PMC_EV_P4_PACKED_SP_UOP:
1821 		__P4SETMASK(psu);
1822 		break;
1823 	case PMC_EV_P4_PACKED_DP_UOP:
1824 		__P4SETMASK(pdu);
1825 		break;
1826 	case PMC_EV_P4_SCALAR_SP_UOP:
1827 		__P4SETMASK(ssu);
1828 		break;
1829 	case PMC_EV_P4_SCALAR_DP_UOP:
1830 		__P4SETMASK(sdu);
1831 		break;
1832 	case PMC_EV_P4_64BIT_MMX_UOP:
1833 		__P4SETMASK(64bmu);
1834 		break;
1835 	case PMC_EV_P4_128BIT_MMX_UOP:
1836 		__P4SETMASK(128bmu);
1837 		break;
1838 	case PMC_EV_P4_X87_FP_UOP:
1839 		__P4SETMASK(xfu);
1840 		break;
1841 	case PMC_EV_P4_X87_SIMD_MOVES_UOP:
1842 		__P4SETMASK(xsmu);
1843 		break;
1844 	case PMC_EV_P4_GLOBAL_POWER_EVENTS:
1845 		__P4SETMASK(gpe);
1846 		break;
1847 	case PMC_EV_P4_TC_MS_XFER:
1848 		__P4SETMASK(tmx);
1849 		break;
1850 	case PMC_EV_P4_UOP_QUEUE_WRITES:
1851 		__P4SETMASK(uqw);
1852 		break;
1853 	case PMC_EV_P4_RETIRED_MISPRED_BRANCH_TYPE:
1854 		__P4SETMASK(rmbt);
1855 		break;
1856 	case PMC_EV_P4_RETIRED_BRANCH_TYPE:
1857 		__P4SETMASK(rbt);
1858 		break;
1859 	case PMC_EV_P4_RESOURCE_STALL:
1860 		__P4SETMASK(rs);
1861 		break;
1862 	case PMC_EV_P4_WC_BUFFER:
1863 		__P4SETMASK(wb);
1864 		break;
1865 	case PMC_EV_P4_BSQ_ACTIVE_ENTRIES:
1866 	case PMC_EV_P4_B2B_CYCLES:
1867 	case PMC_EV_P4_BNR:
1868 	case PMC_EV_P4_SNOOP:
1869 	case PMC_EV_P4_RESPONSE:
1870 		break;
1871 	case PMC_EV_P4_FRONT_END_EVENT:
1872 		__P4SETMASK(fee);
1873 		break;
1874 	case PMC_EV_P4_EXECUTION_EVENT:
1875 		__P4SETMASK(ee);
1876 		break;
1877 	case PMC_EV_P4_REPLAY_EVENT:
1878 		__P4SETMASK(re);
1879 		break;
1880 	case PMC_EV_P4_INSTR_RETIRED:
1881 		__P4SETMASK(insret);
1882 		break;
1883 	case PMC_EV_P4_UOPS_RETIRED:
1884 		__P4SETMASK(ur);
1885 		break;
1886 	case PMC_EV_P4_UOP_TYPE:
1887 		__P4SETMASK(ut);
1888 		break;
1889 	case PMC_EV_P4_BRANCH_RETIRED:
1890 		__P4SETMASK(br);
1891 		break;
1892 	case PMC_EV_P4_MISPRED_BRANCH_RETIRED:
1893 		__P4SETMASK(mbr);
1894 		break;
1895 	case PMC_EV_P4_X87_ASSIST:
1896 		__P4SETMASK(xa);
1897 		break;
1898 	case PMC_EV_P4_MACHINE_CLEAR:
1899 		__P4SETMASK(machclr);
1900 		break;
1901 	default:
1902 		return (-1);
1903 	}
1904 
1905 	/* process additional flags */
1906 	while ((p = strsep(&ctrspec, ",")) != NULL) {
1907 		if (KWPREFIXMATCH(p, P4_KW_ACTIVE)) {
1908 			q = strchr(p, '=');
1909 			if (*++q == '\0') /* skip '=' */
1910 				return (-1);
1911 
1912 			if (strcasecmp(q, P4_KW_ACTIVE_NONE) == 0)
1913 				cccractivemask = 0x0;
1914 			else if (strcasecmp(q, P4_KW_ACTIVE_SINGLE) == 0)
1915 				cccractivemask = 0x1;
1916 			else if (strcasecmp(q, P4_KW_ACTIVE_BOTH) == 0)
1917 				cccractivemask = 0x2;
1918 			else if (strcasecmp(q, P4_KW_ACTIVE_ANY) == 0)
1919 				cccractivemask = 0x3;
1920 			else
1921 				return (-1);
1922 
1923 		} else if (KWPREFIXMATCH(p, P4_KW_BUSREQTYPE)) {
1924 			if (has_busreqtype == 0)
1925 				return (-1);
1926 
1927 			q = strchr(p, '=');
1928 			if (*++q == '\0') /* skip '=' */
1929 				return (-1);
1930 
1931 			count = strtol(q, &e, 0);
1932 			if (e == q || *e != '\0')
1933 				return (-1);
1934 			evmask = (evmask & ~0x1F) | (count & 0x1F);
1935 		} else if (KWMATCH(p, P4_KW_CASCADE))
1936 			pmc_config->pm_caps |= PMC_CAP_CASCADE;
1937 		else if (KWMATCH(p, P4_KW_EDGE))
1938 			pmc_config->pm_caps |= PMC_CAP_EDGE;
1939 		else if (KWMATCH(p, P4_KW_INV))
1940 			pmc_config->pm_caps |= PMC_CAP_INVERT;
1941 		else if (KWPREFIXMATCH(p, P4_KW_MASK "=")) {
1942 			if ((n = pmc_parse_mask(pmask, p, &evmask)) < 0)
1943 				return (-1);
1944 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
1945 		} else if (KWMATCH(p, P4_KW_OS))
1946 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
1947 		else if (KWMATCH(p, P4_KW_PRECISE))
1948 			pmc_config->pm_caps |= PMC_CAP_PRECISE;
1949 		else if (KWPREFIXMATCH(p, P4_KW_TAG "=")) {
1950 			if (has_tag == 0)
1951 				return (-1);
1952 
1953 			q = strchr(p, '=');
1954 			if (*++q == '\0') /* skip '=' */
1955 				return (-1);
1956 
1957 			count = strtol(q, &e, 0);
1958 			if (e == q || *e != '\0')
1959 				return (-1);
1960 
1961 			pmc_config->pm_caps |= PMC_CAP_TAGGING;
1962 			pmc_config->pm_md.pm_p4.pm_p4_escrconfig |=
1963 			    P4_ESCR_TO_TAG_VALUE(count);
1964 		} else if (KWPREFIXMATCH(p, P4_KW_THRESHOLD "=")) {
1965 			q = strchr(p, '=');
1966 			if (*++q == '\0') /* skip '=' */
1967 				return (-1);
1968 
1969 			count = strtol(q, &e, 0);
1970 			if (e == q || *e != '\0')
1971 				return (-1);
1972 
1973 			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
1974 			pmc_config->pm_md.pm_p4.pm_p4_cccrconfig &=
1975 			    ~P4_CCCR_THRESHOLD_MASK;
1976 			pmc_config->pm_md.pm_p4.pm_p4_cccrconfig |=
1977 			    P4_CCCR_TO_THRESHOLD(count);
1978 		} else if (KWMATCH(p, P4_KW_USR))
1979 			pmc_config->pm_caps |= PMC_CAP_USER;
1980 		else
1981 			return (-1);
1982 	}
1983 
1984 	/* other post processing */
1985 	if (pe == PMC_EV_P4_IOQ_ALLOCATION ||
1986 	    pe == PMC_EV_P4_FSB_DATA_ACTIVITY ||
1987 	    pe == PMC_EV_P4_BSQ_ALLOCATION)
1988 		pmc_config->pm_caps |= PMC_CAP_EDGE;
1989 
1990 	/* fill in thread activity mask */
1991 	pmc_config->pm_md.pm_p4.pm_p4_cccrconfig |=
1992 	    P4_CCCR_TO_ACTIVE_THREAD(cccractivemask);
1993 
1994 	if (evmask)
1995 		pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
1996 
1997 	switch (pe) {
1998 	case PMC_EV_P4_FSB_DATA_ACTIVITY:
1999 		if ((evmask & 0x06) == 0x06 ||
2000 		    (evmask & 0x18) == 0x18)
2001 			return (-1); /* can't have own+other bits together */
2002 		if (evmask == 0) /* default:drdy-{drv,own}+dbsy{drv,own} */
2003 			evmask = 0x1D;
2004 		break;
2005 	case PMC_EV_P4_MACHINE_CLEAR:
2006 		/* only one bit is allowed to be set */
2007 		if ((evmask & (evmask - 1)) != 0)
2008 			return (-1);
2009 		if (evmask == 0) {
2010 			evmask = 0x1;	/* 'CLEAR' */
2011 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
2012 		}
2013 		break;
2014 	default:
2015 		if (evmask == 0 && pmask) {
2016 			for (pm = pmask; pm->pm_name; pm++)
2017 				evmask |= pm->pm_value;
2018 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
2019 		}
2020 	}
2021 
2022 	pmc_config->pm_md.pm_p4.pm_p4_escrconfig =
2023 	    P4_ESCR_TO_EVENT_MASK(evmask);
2024 
2025 	return (0);
2026 }
2027 
2028 #endif
2029 
2030 #if defined(__i386__)
2031 
2032 /*
2033  * Pentium style PMCs
2034  */
2035 
2036 static struct pmc_event_alias p5_aliases[] = {
2037 	EV_ALIAS("branches",		"p5-taken-branches"),
2038 	EV_ALIAS("cycles",		"tsc"),
2039 	EV_ALIAS("dc-misses",		"p5-data-read-miss-or-write-miss"),
2040 	EV_ALIAS("ic-misses",		"p5-code-cache-miss"),
2041 	EV_ALIAS("instructions",	"p5-instructions-executed"),
2042 	EV_ALIAS("interrupts",		"p5-hardware-interrupts"),
2043 	EV_ALIAS("unhalted-cycles",
2044 	    "p5-number-of-cycles-not-in-halt-state"),
2045 	EV_ALIAS(NULL, NULL)
2046 };
2047 
2048 static int
2049 p5_allocate_pmc(enum pmc_event pe, char *ctrspec,
2050     struct pmc_op_pmcallocate *pmc_config)
2051 {
2052 	return (-1 || pe || ctrspec || pmc_config); /* shut up gcc */
2053 }
2054 
2055 /*
2056  * Pentium Pro style PMCs.  These PMCs are found in Pentium II, Pentium III,
2057  * and Pentium M CPUs.
2058  */
2059 
2060 static struct pmc_event_alias p6_aliases[] = {
2061 	EV_ALIAS("branches",		"p6-br-inst-retired"),
2062 	EV_ALIAS("branch-mispredicts",	"p6-br-miss-pred-retired"),
2063 	EV_ALIAS("cycles",		"tsc"),
2064 	EV_ALIAS("dc-misses",		"p6-dcu-lines-in"),
2065 	EV_ALIAS("ic-misses",		"p6-ifu-fetch-miss"),
2066 	EV_ALIAS("instructions",	"p6-inst-retired"),
2067 	EV_ALIAS("interrupts",		"p6-hw-int-rx"),
2068 	EV_ALIAS("unhalted-cycles",	"p6-cpu-clk-unhalted"),
2069 	EV_ALIAS(NULL, NULL)
2070 };
2071 
2072 #define	P6_KW_CMASK	"cmask"
2073 #define	P6_KW_EDGE	"edge"
2074 #define	P6_KW_INV	"inv"
2075 #define	P6_KW_OS	"os"
2076 #define	P6_KW_UMASK	"umask"
2077 #define	P6_KW_USR	"usr"
2078 
2079 static struct pmc_masks p6_mask_mesi[] = {
2080 	PMCMASK(m,	0x01),
2081 	PMCMASK(e,	0x02),
2082 	PMCMASK(s,	0x04),
2083 	PMCMASK(i,	0x08),
2084 	NULLMASK
2085 };
2086 
2087 static struct pmc_masks p6_mask_mesihw[] = {
2088 	PMCMASK(m,	0x01),
2089 	PMCMASK(e,	0x02),
2090 	PMCMASK(s,	0x04),
2091 	PMCMASK(i,	0x08),
2092 	PMCMASK(nonhw,	0x00),
2093 	PMCMASK(hw,	0x10),
2094 	PMCMASK(both,	0x30),
2095 	NULLMASK
2096 };
2097 
2098 static struct pmc_masks p6_mask_hw[] = {
2099 	PMCMASK(nonhw,	0x00),
2100 	PMCMASK(hw,	0x10),
2101 	PMCMASK(both,	0x30),
2102 	NULLMASK
2103 };
2104 
2105 static struct pmc_masks p6_mask_any[] = {
2106 	PMCMASK(self,	0x00),
2107 	PMCMASK(any,	0x20),
2108 	NULLMASK
2109 };
2110 
2111 static struct pmc_masks p6_mask_ekp[] = {
2112 	PMCMASK(nta,	0x00),
2113 	PMCMASK(t1,	0x01),
2114 	PMCMASK(t2,	0x02),
2115 	PMCMASK(wos,	0x03),
2116 	NULLMASK
2117 };
2118 
2119 static struct pmc_masks p6_mask_pps[] = {
2120 	PMCMASK(packed-and-scalar, 0x00),
2121 	PMCMASK(scalar,	0x01),
2122 	NULLMASK
2123 };
2124 
2125 static struct pmc_masks p6_mask_mite[] = {
2126 	PMCMASK(packed-multiply,	 0x01),
2127 	PMCMASK(packed-shift,		0x02),
2128 	PMCMASK(pack,			0x04),
2129 	PMCMASK(unpack,			0x08),
2130 	PMCMASK(packed-logical,		0x10),
2131 	PMCMASK(packed-arithmetic,	0x20),
2132 	NULLMASK
2133 };
2134 
2135 static struct pmc_masks p6_mask_fmt[] = {
2136 	PMCMASK(mmxtofp,	0x00),
2137 	PMCMASK(fptommx,	0x01),
2138 	NULLMASK
2139 };
2140 
2141 static struct pmc_masks p6_mask_sr[] = {
2142 	PMCMASK(es,	0x01),
2143 	PMCMASK(ds,	0x02),
2144 	PMCMASK(fs,	0x04),
2145 	PMCMASK(gs,	0x08),
2146 	NULLMASK
2147 };
2148 
2149 static struct pmc_masks p6_mask_eet[] = {
2150 	PMCMASK(all,	0x00),
2151 	PMCMASK(freq,	0x02),
2152 	NULLMASK
2153 };
2154 
2155 static struct pmc_masks p6_mask_efur[] = {
2156 	PMCMASK(all,	0x00),
2157 	PMCMASK(loadop,	0x01),
2158 	PMCMASK(stdsta,	0x02),
2159 	NULLMASK
2160 };
2161 
2162 static struct pmc_masks p6_mask_essir[] = {
2163 	PMCMASK(sse-packed-single,	0x00),
2164 	PMCMASK(sse-packed-single-scalar-single, 0x01),
2165 	PMCMASK(sse2-packed-double,	0x02),
2166 	PMCMASK(sse2-scalar-double,	0x03),
2167 	NULLMASK
2168 };
2169 
2170 static struct pmc_masks p6_mask_esscir[] = {
2171 	PMCMASK(sse-packed-single,	0x00),
2172 	PMCMASK(sse-scalar-single,	0x01),
2173 	PMCMASK(sse2-packed-double,	0x02),
2174 	PMCMASK(sse2-scalar-double,	0x03),
2175 	NULLMASK
2176 };
2177 
2178 /* P6 event parser */
2179 static int
2180 p6_allocate_pmc(enum pmc_event pe, char *ctrspec,
2181     struct pmc_op_pmcallocate *pmc_config)
2182 {
2183 	char *e, *p, *q;
2184 	uint64_t evmask;
2185 	int count, n;
2186 	const struct pmc_masks *pm, *pmask;
2187 
2188 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
2189 	pmc_config->pm_md.pm_ppro.pm_ppro_config = 0;
2190 
2191 	evmask = 0;
2192 
2193 #define	P6MASKSET(M)	pmask = p6_mask_ ## M
2194 
2195 	switch(pe) {
2196 	case PMC_EV_P6_L2_IFETCH:	P6MASKSET(mesi); break;
2197 	case PMC_EV_P6_L2_LD:		P6MASKSET(mesi); break;
2198 	case PMC_EV_P6_L2_ST:		P6MASKSET(mesi); break;
2199 	case PMC_EV_P6_L2_RQSTS:	P6MASKSET(mesi); break;
2200 	case PMC_EV_P6_BUS_DRDY_CLOCKS:
2201 	case PMC_EV_P6_BUS_LOCK_CLOCKS:
2202 	case PMC_EV_P6_BUS_TRAN_BRD:
2203 	case PMC_EV_P6_BUS_TRAN_RFO:
2204 	case PMC_EV_P6_BUS_TRANS_WB:
2205 	case PMC_EV_P6_BUS_TRAN_IFETCH:
2206 	case PMC_EV_P6_BUS_TRAN_INVAL:
2207 	case PMC_EV_P6_BUS_TRAN_PWR:
2208 	case PMC_EV_P6_BUS_TRANS_P:
2209 	case PMC_EV_P6_BUS_TRANS_IO:
2210 	case PMC_EV_P6_BUS_TRAN_DEF:
2211 	case PMC_EV_P6_BUS_TRAN_BURST:
2212 	case PMC_EV_P6_BUS_TRAN_ANY:
2213 	case PMC_EV_P6_BUS_TRAN_MEM:
2214 		P6MASKSET(any);	break;
2215 	case PMC_EV_P6_EMON_KNI_PREF_DISPATCHED:
2216 	case PMC_EV_P6_EMON_KNI_PREF_MISS:
2217 		P6MASKSET(ekp); break;
2218 	case PMC_EV_P6_EMON_KNI_INST_RETIRED:
2219 	case PMC_EV_P6_EMON_KNI_COMP_INST_RET:
2220 		P6MASKSET(pps);	break;
2221 	case PMC_EV_P6_MMX_INSTR_TYPE_EXEC:
2222 		P6MASKSET(mite); break;
2223 	case PMC_EV_P6_FP_MMX_TRANS:
2224 		P6MASKSET(fmt);	break;
2225 	case PMC_EV_P6_SEG_RENAME_STALLS:
2226 	case PMC_EV_P6_SEG_REG_RENAMES:
2227 		P6MASKSET(sr);	break;
2228 	case PMC_EV_P6_EMON_EST_TRANS:
2229 		P6MASKSET(eet);	break;
2230 	case PMC_EV_P6_EMON_FUSED_UOPS_RET:
2231 		P6MASKSET(efur); break;
2232 	case PMC_EV_P6_EMON_SSE_SSE2_INST_RETIRED:
2233 		P6MASKSET(essir); break;
2234 	case PMC_EV_P6_EMON_SSE_SSE2_COMP_INST_RETIRED:
2235 		P6MASKSET(esscir); break;
2236 	default:
2237 		pmask = NULL;
2238 		break;
2239 	}
2240 
2241 	/* Pentium M PMCs have a few events with different semantics */
2242 	if (cpu_info.pm_cputype == PMC_CPU_INTEL_PM) {
2243 		if (pe == PMC_EV_P6_L2_LD ||
2244 		    pe == PMC_EV_P6_L2_LINES_IN ||
2245 		    pe == PMC_EV_P6_L2_LINES_OUT)
2246 			P6MASKSET(mesihw);
2247 		else if (pe == PMC_EV_P6_L2_M_LINES_OUTM)
2248 			P6MASKSET(hw);
2249 	}
2250 
2251 	/* Parse additional modifiers if present */
2252 	while ((p = strsep(&ctrspec, ",")) != NULL) {
2253 		if (KWPREFIXMATCH(p, P6_KW_CMASK "=")) {
2254 			q = strchr(p, '=');
2255 			if (*++q == '\0') /* skip '=' */
2256 				return (-1);
2257 			count = strtol(q, &e, 0);
2258 			if (e == q || *e != '\0')
2259 				return (-1);
2260 			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
2261 			pmc_config->pm_md.pm_ppro.pm_ppro_config |=
2262 			    P6_EVSEL_TO_CMASK(count);
2263 		} else if (KWMATCH(p, P6_KW_EDGE)) {
2264 			pmc_config->pm_caps |= PMC_CAP_EDGE;
2265 		} else if (KWMATCH(p, P6_KW_INV)) {
2266 			pmc_config->pm_caps |= PMC_CAP_INVERT;
2267 		} else if (KWMATCH(p, P6_KW_OS)) {
2268 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
2269 		} else if (KWPREFIXMATCH(p, P6_KW_UMASK "=")) {
2270 			evmask = 0;
2271 			if ((n = pmc_parse_mask(pmask, p, &evmask)) < 0)
2272 				return (-1);
2273 			if ((pe == PMC_EV_P6_BUS_DRDY_CLOCKS ||
2274 			     pe == PMC_EV_P6_BUS_LOCK_CLOCKS ||
2275 			     pe == PMC_EV_P6_BUS_TRAN_BRD ||
2276 			     pe == PMC_EV_P6_BUS_TRAN_RFO ||
2277 			     pe == PMC_EV_P6_BUS_TRAN_IFETCH ||
2278 			     pe == PMC_EV_P6_BUS_TRAN_INVAL ||
2279 			     pe == PMC_EV_P6_BUS_TRAN_PWR ||
2280 			     pe == PMC_EV_P6_BUS_TRAN_DEF ||
2281 			     pe == PMC_EV_P6_BUS_TRAN_BURST ||
2282 			     pe == PMC_EV_P6_BUS_TRAN_ANY ||
2283 			     pe == PMC_EV_P6_BUS_TRAN_MEM ||
2284 			     pe == PMC_EV_P6_BUS_TRANS_IO ||
2285 			     pe == PMC_EV_P6_BUS_TRANS_P ||
2286 			     pe == PMC_EV_P6_BUS_TRANS_WB ||
2287 			     pe == PMC_EV_P6_EMON_EST_TRANS ||
2288 			     pe == PMC_EV_P6_EMON_FUSED_UOPS_RET ||
2289 			     pe == PMC_EV_P6_EMON_KNI_COMP_INST_RET ||
2290 			     pe == PMC_EV_P6_EMON_KNI_INST_RETIRED ||
2291 			     pe == PMC_EV_P6_EMON_KNI_PREF_DISPATCHED ||
2292 			     pe == PMC_EV_P6_EMON_KNI_PREF_MISS ||
2293 			     pe == PMC_EV_P6_EMON_SSE_SSE2_COMP_INST_RETIRED ||
2294 			     pe == PMC_EV_P6_EMON_SSE_SSE2_INST_RETIRED ||
2295 			     pe == PMC_EV_P6_FP_MMX_TRANS)
2296 			    && (n > 1))	/* Only one mask keyword is allowed. */
2297 				return (-1);
2298 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
2299 		} else if (KWMATCH(p, P6_KW_USR)) {
2300 			pmc_config->pm_caps |= PMC_CAP_USER;
2301 		} else
2302 			return (-1);
2303 	}
2304 
2305 	/* post processing */
2306 	switch (pe) {
2307 
2308 		/*
2309 		 * The following events default to an evmask of 0
2310 		 */
2311 
2312 		/* default => 'self' */
2313 	case PMC_EV_P6_BUS_DRDY_CLOCKS:
2314 	case PMC_EV_P6_BUS_LOCK_CLOCKS:
2315 	case PMC_EV_P6_BUS_TRAN_BRD:
2316 	case PMC_EV_P6_BUS_TRAN_RFO:
2317 	case PMC_EV_P6_BUS_TRANS_WB:
2318 	case PMC_EV_P6_BUS_TRAN_IFETCH:
2319 	case PMC_EV_P6_BUS_TRAN_INVAL:
2320 	case PMC_EV_P6_BUS_TRAN_PWR:
2321 	case PMC_EV_P6_BUS_TRANS_P:
2322 	case PMC_EV_P6_BUS_TRANS_IO:
2323 	case PMC_EV_P6_BUS_TRAN_DEF:
2324 	case PMC_EV_P6_BUS_TRAN_BURST:
2325 	case PMC_EV_P6_BUS_TRAN_ANY:
2326 	case PMC_EV_P6_BUS_TRAN_MEM:
2327 
2328 		/* default => 'nta' */
2329 	case PMC_EV_P6_EMON_KNI_PREF_DISPATCHED:
2330 	case PMC_EV_P6_EMON_KNI_PREF_MISS:
2331 
2332 		/* default => 'packed and scalar' */
2333 	case PMC_EV_P6_EMON_KNI_INST_RETIRED:
2334 	case PMC_EV_P6_EMON_KNI_COMP_INST_RET:
2335 
2336 		/* default => 'mmx to fp transitions' */
2337 	case PMC_EV_P6_FP_MMX_TRANS:
2338 
2339 		/* default => 'SSE Packed Single' */
2340 	case PMC_EV_P6_EMON_SSE_SSE2_INST_RETIRED:
2341 	case PMC_EV_P6_EMON_SSE_SSE2_COMP_INST_RETIRED:
2342 
2343 		/* default => 'all fused micro-ops' */
2344 	case PMC_EV_P6_EMON_FUSED_UOPS_RET:
2345 
2346 		/* default => 'all transitions' */
2347 	case PMC_EV_P6_EMON_EST_TRANS:
2348 		break;
2349 
2350 	case PMC_EV_P6_MMX_UOPS_EXEC:
2351 		evmask = 0x0F;		/* only value allowed */
2352 		break;
2353 
2354 	default:
2355 		/*
2356 		 * For all other events, set the default event mask
2357 		 * to a logical OR of all the allowed event mask bits.
2358 		 */
2359 		if (evmask == 0 && pmask) {
2360 			for (pm = pmask; pm->pm_name; pm++)
2361 				evmask |= pm->pm_value;
2362 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
2363 		}
2364 
2365 		break;
2366 	}
2367 
2368 	if (pmc_config->pm_caps & PMC_CAP_QUALIFIER)
2369 		pmc_config->pm_md.pm_ppro.pm_ppro_config |=
2370 		    P6_EVSEL_TO_UMASK(evmask);
2371 
2372 	return (0);
2373 }
2374 
2375 #endif
2376 
2377 #if	defined(__i386__) || defined(__amd64__)
2378 static int
2379 tsc_allocate_pmc(enum pmc_event pe, char *ctrspec,
2380     struct pmc_op_pmcallocate *pmc_config)
2381 {
2382 	if (pe != PMC_EV_TSC_TSC)
2383 		return (-1);
2384 
2385 	/* TSC events must be unqualified. */
2386 	if (ctrspec && *ctrspec != '\0')
2387 		return (-1);
2388 
2389 	pmc_config->pm_md.pm_amd.pm_amd_config = 0;
2390 	pmc_config->pm_caps |= PMC_CAP_READ;
2391 
2392 	return (0);
2393 }
2394 #endif
2395 
2396 static struct pmc_event_alias generic_aliases[] = {
2397 	EV_ALIAS("instructions",		"SOFT-CLOCK.HARD"),
2398 	EV_ALIAS(NULL, NULL)
2399 };
2400 
2401 static int
2402 soft_allocate_pmc(enum pmc_event pe, char *ctrspec,
2403     struct pmc_op_pmcallocate *pmc_config)
2404 {
2405 	(void)ctrspec;
2406 	(void)pmc_config;
2407 
2408 	if ((int)pe < PMC_EV_SOFT_FIRST || (int)pe > PMC_EV_SOFT_LAST)
2409 		return (-1);
2410 
2411 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
2412 	return (0);
2413 }
2414 
2415 #if	defined(__arm__)
2416 #if	defined(__XSCALE__)
2417 
2418 static struct pmc_event_alias xscale_aliases[] = {
2419 	EV_ALIAS("branches",		"BRANCH_RETIRED"),
2420 	EV_ALIAS("branch-mispredicts",	"BRANCH_MISPRED"),
2421 	EV_ALIAS("dc-misses",		"DC_MISS"),
2422 	EV_ALIAS("ic-misses",		"IC_MISS"),
2423 	EV_ALIAS("instructions",	"INSTR_RETIRED"),
2424 	EV_ALIAS(NULL, NULL)
2425 };
2426 static int
2427 xscale_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
2428     struct pmc_op_pmcallocate *pmc_config __unused)
2429 {
2430 	switch (pe) {
2431 	default:
2432 		break;
2433 	}
2434 
2435 	return (0);
2436 }
2437 #endif
2438 
2439 static struct pmc_event_alias armv7_aliases[] = {
2440 	EV_ALIAS("dc-misses",		"L1_DCACHE_REFILL"),
2441 	EV_ALIAS("ic-misses",		"L1_ICACHE_REFILL"),
2442 	EV_ALIAS("instructions",	"INSTR_EXECUTED"),
2443 	EV_ALIAS(NULL, NULL)
2444 };
2445 static int
2446 armv7_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
2447     struct pmc_op_pmcallocate *pmc_config __unused)
2448 {
2449 	switch (pe) {
2450 	default:
2451 		break;
2452 	}
2453 
2454 	return (0);
2455 }
2456 #endif
2457 
2458 #if	defined(__aarch64__)
2459 static struct pmc_event_alias cortex_a53_aliases[] = {
2460 	EV_ALIAS(NULL, NULL)
2461 };
2462 static struct pmc_event_alias cortex_a57_aliases[] = {
2463 	EV_ALIAS(NULL, NULL)
2464 };
2465 static int
2466 arm64_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
2467     struct pmc_op_pmcallocate *pmc_config __unused)
2468 {
2469 	switch (pe) {
2470 	default:
2471 		break;
2472 	}
2473 
2474 	return (0);
2475 }
2476 #endif
2477 
2478 #if defined(__mips__)
2479 
2480 static struct pmc_event_alias mips24k_aliases[] = {
2481 	EV_ALIAS("instructions",	"INSTR_EXECUTED"),
2482 	EV_ALIAS("branches",		"BRANCH_COMPLETED"),
2483 	EV_ALIAS("branch-mispredicts",	"BRANCH_MISPRED"),
2484 	EV_ALIAS(NULL, NULL)
2485 };
2486 
2487 static struct pmc_event_alias mips74k_aliases[] = {
2488 	EV_ALIAS("instructions",	"INSTR_EXECUTED"),
2489 	EV_ALIAS("branches",		"BRANCH_INSNS"),
2490 	EV_ALIAS("branch-mispredicts",	"MISPREDICTED_BRANCH_INSNS"),
2491 	EV_ALIAS(NULL, NULL)
2492 };
2493 
2494 static struct pmc_event_alias octeon_aliases[] = {
2495 	EV_ALIAS("instructions",	"RET"),
2496 	EV_ALIAS("branches",		"BR"),
2497 	EV_ALIAS("branch-mispredicts",	"BRMIS"),
2498 	EV_ALIAS(NULL, NULL)
2499 };
2500 
2501 #define	MIPS_KW_OS		"os"
2502 #define	MIPS_KW_USR		"usr"
2503 #define	MIPS_KW_ANYTHREAD	"anythread"
2504 
2505 static int
2506 mips_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
2507 		  struct pmc_op_pmcallocate *pmc_config __unused)
2508 {
2509 	char *p;
2510 
2511 	(void) pe;
2512 
2513 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
2514 
2515 	while ((p = strsep(&ctrspec, ",")) != NULL) {
2516 		if (KWMATCH(p, MIPS_KW_OS))
2517 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
2518 		else if (KWMATCH(p, MIPS_KW_USR))
2519 			pmc_config->pm_caps |= PMC_CAP_USER;
2520 		else if (KWMATCH(p, MIPS_KW_ANYTHREAD))
2521 			pmc_config->pm_caps |= (PMC_CAP_USER | PMC_CAP_SYSTEM);
2522 		else
2523 			return (-1);
2524 	}
2525 
2526 	return (0);
2527 }
2528 
2529 #endif /* __mips__ */
2530 
2531 #if defined(__powerpc__)
2532 
2533 static struct pmc_event_alias ppc7450_aliases[] = {
2534 	EV_ALIAS("instructions",	"INSTR_COMPLETED"),
2535 	EV_ALIAS("branches",		"BRANCHES_COMPLETED"),
2536 	EV_ALIAS("branch-mispredicts",	"MISPREDICTED_BRANCHES"),
2537 	EV_ALIAS(NULL, NULL)
2538 };
2539 
2540 static struct pmc_event_alias ppc970_aliases[] = {
2541 	EV_ALIAS("instructions", "INSTR_COMPLETED"),
2542 	EV_ALIAS("cycles",       "CYCLES"),
2543 	EV_ALIAS(NULL, NULL)
2544 };
2545 
2546 static struct pmc_event_alias e500_aliases[] = {
2547 	EV_ALIAS("instructions", "INSTR_COMPLETED"),
2548 	EV_ALIAS("cycles",       "CYCLES"),
2549 	EV_ALIAS(NULL, NULL)
2550 };
2551 
2552 #define	POWERPC_KW_OS		"os"
2553 #define	POWERPC_KW_USR		"usr"
2554 #define	POWERPC_KW_ANYTHREAD	"anythread"
2555 
2556 static int
2557 powerpc_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
2558 		     struct pmc_op_pmcallocate *pmc_config __unused)
2559 {
2560 	char *p;
2561 
2562 	(void) pe;
2563 
2564 	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
2565 
2566 	while ((p = strsep(&ctrspec, ",")) != NULL) {
2567 		if (KWMATCH(p, POWERPC_KW_OS))
2568 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
2569 		else if (KWMATCH(p, POWERPC_KW_USR))
2570 			pmc_config->pm_caps |= PMC_CAP_USER;
2571 		else if (KWMATCH(p, POWERPC_KW_ANYTHREAD))
2572 			pmc_config->pm_caps |= (PMC_CAP_USER | PMC_CAP_SYSTEM);
2573 		else
2574 			return (-1);
2575 	}
2576 
2577 	return (0);
2578 }
2579 
2580 #endif /* __powerpc__ */
2581 
2582 
2583 /*
2584  * Match an event name `name' with its canonical form.
2585  *
2586  * Matches are case insensitive and spaces, periods, underscores and
2587  * hyphen characters are considered to match each other.
2588  *
2589  * Returns 1 for a match, 0 otherwise.
2590  */
2591 
2592 static int
2593 pmc_match_event_name(const char *name, const char *canonicalname)
2594 {
2595 	int cc, nc;
2596 	const unsigned char *c, *n;
2597 
2598 	c = (const unsigned char *) canonicalname;
2599 	n = (const unsigned char *) name;
2600 
2601 	for (; (nc = *n) && (cc = *c); n++, c++) {
2602 
2603 		if ((nc == ' ' || nc == '_' || nc == '-' || nc == '.') &&
2604 		    (cc == ' ' || cc == '_' || cc == '-' || cc == '.'))
2605 			continue;
2606 
2607 		if (toupper(nc) == toupper(cc))
2608 			continue;
2609 
2610 
2611 		return (0);
2612 	}
2613 
2614 	if (*n == '\0' && *c == '\0')
2615 		return (1);
2616 
2617 	return (0);
2618 }
2619 
2620 /*
2621  * Match an event name against all the event named supported by a
2622  * PMC class.
2623  *
2624  * Returns an event descriptor pointer on match or NULL otherwise.
2625  */
2626 static const struct pmc_event_descr *
2627 pmc_match_event_class(const char *name,
2628     const struct pmc_class_descr *pcd)
2629 {
2630 	size_t n;
2631 	const struct pmc_event_descr *ev;
2632 
2633 	ev = pcd->pm_evc_event_table;
2634 	for (n = 0; n < pcd->pm_evc_event_table_size; n++, ev++)
2635 		if (pmc_match_event_name(name, ev->pm_ev_name))
2636 			return (ev);
2637 
2638 	return (NULL);
2639 }
2640 
2641 static int
2642 pmc_mdep_is_compatible_class(enum pmc_class pc)
2643 {
2644 	size_t n;
2645 
2646 	for (n = 0; n < pmc_mdep_class_list_size; n++)
2647 		if (pmc_mdep_class_list[n] == pc)
2648 			return (1);
2649 	return (0);
2650 }
2651 
2652 /*
2653  * API entry points
2654  */
2655 
2656 int
2657 pmc_allocate(const char *ctrspec, enum pmc_mode mode,
2658     uint32_t flags, int cpu, pmc_id_t *pmcid)
2659 {
2660 	size_t n;
2661 	int retval;
2662 	char *r, *spec_copy;
2663 	const char *ctrname;
2664 	const struct pmc_event_descr *ev;
2665 	const struct pmc_event_alias *alias;
2666 	struct pmc_op_pmcallocate pmc_config;
2667 	const struct pmc_class_descr *pcd;
2668 
2669 	spec_copy = NULL;
2670 	retval    = -1;
2671 
2672 	if (mode != PMC_MODE_SS && mode != PMC_MODE_TS &&
2673 	    mode != PMC_MODE_SC && mode != PMC_MODE_TC) {
2674 		errno = EINVAL;
2675 		goto out;
2676 	}
2677 
2678 	/* replace an event alias with the canonical event specifier */
2679 	if (pmc_mdep_event_aliases)
2680 		for (alias = pmc_mdep_event_aliases; alias->pm_alias; alias++)
2681 			if (!strcasecmp(ctrspec, alias->pm_alias)) {
2682 				spec_copy = strdup(alias->pm_spec);
2683 				break;
2684 			}
2685 
2686 	if (spec_copy == NULL)
2687 		spec_copy = strdup(ctrspec);
2688 
2689 	r = spec_copy;
2690 	ctrname = strsep(&r, ",");
2691 
2692 	/*
2693 	 * If a explicit class prefix was given by the user, restrict the
2694 	 * search for the event to the specified PMC class.
2695 	 */
2696 	ev = NULL;
2697 	for (n = 0; n < PMC_CLASS_TABLE_SIZE; n++) {
2698 		pcd = pmc_class_table[n];
2699 		if (pmc_mdep_is_compatible_class(pcd->pm_evc_class) &&
2700 		    strncasecmp(ctrname, pcd->pm_evc_name,
2701 				pcd->pm_evc_name_size) == 0) {
2702 			if ((ev = pmc_match_event_class(ctrname +
2703 			    pcd->pm_evc_name_size, pcd)) == NULL) {
2704 				errno = EINVAL;
2705 				goto out;
2706 			}
2707 			break;
2708 		}
2709 	}
2710 
2711 	/*
2712 	 * Otherwise, search for this event in all compatible PMC
2713 	 * classes.
2714 	 */
2715 	for (n = 0; ev == NULL && n < PMC_CLASS_TABLE_SIZE; n++) {
2716 		pcd = pmc_class_table[n];
2717 		if (pmc_mdep_is_compatible_class(pcd->pm_evc_class))
2718 			ev = pmc_match_event_class(ctrname, pcd);
2719 	}
2720 
2721 	if (ev == NULL) {
2722 		errno = EINVAL;
2723 		goto out;
2724 	}
2725 
2726 	bzero(&pmc_config, sizeof(pmc_config));
2727 	pmc_config.pm_ev    = ev->pm_ev_code;
2728 	pmc_config.pm_class = pcd->pm_evc_class;
2729 	pmc_config.pm_cpu   = cpu;
2730 	pmc_config.pm_mode  = mode;
2731 	pmc_config.pm_flags = flags;
2732 
2733 	if (PMC_IS_SAMPLING_MODE(mode))
2734 		pmc_config.pm_caps |= PMC_CAP_INTERRUPT;
2735 
2736  	if (pcd->pm_evc_allocate_pmc(ev->pm_ev_code, r, &pmc_config) < 0) {
2737 		errno = EINVAL;
2738 		goto out;
2739 	}
2740 
2741 	if (PMC_CALL(PMCALLOCATE, &pmc_config) < 0)
2742 		goto out;
2743 
2744 	*pmcid = pmc_config.pm_pmcid;
2745 
2746 	retval = 0;
2747 
2748  out:
2749 	if (spec_copy)
2750 		free(spec_copy);
2751 
2752 	return (retval);
2753 }
2754 
2755 int
2756 pmc_attach(pmc_id_t pmc, pid_t pid)
2757 {
2758 	struct pmc_op_pmcattach pmc_attach_args;
2759 
2760 	pmc_attach_args.pm_pmc = pmc;
2761 	pmc_attach_args.pm_pid = pid;
2762 
2763 	return (PMC_CALL(PMCATTACH, &pmc_attach_args));
2764 }
2765 
2766 int
2767 pmc_capabilities(pmc_id_t pmcid, uint32_t *caps)
2768 {
2769 	unsigned int i;
2770 	enum pmc_class cl;
2771 
2772 	cl = PMC_ID_TO_CLASS(pmcid);
2773 	for (i = 0; i < cpu_info.pm_nclass; i++)
2774 		if (cpu_info.pm_classes[i].pm_class == cl) {
2775 			*caps = cpu_info.pm_classes[i].pm_caps;
2776 			return (0);
2777 		}
2778 	errno = EINVAL;
2779 	return (-1);
2780 }
2781 
2782 int
2783 pmc_configure_logfile(int fd)
2784 {
2785 	struct pmc_op_configurelog cla;
2786 
2787 	cla.pm_logfd = fd;
2788 	if (PMC_CALL(CONFIGURELOG, &cla) < 0)
2789 		return (-1);
2790 	return (0);
2791 }
2792 
2793 int
2794 pmc_cpuinfo(const struct pmc_cpuinfo **pci)
2795 {
2796 	if (pmc_syscall == -1) {
2797 		errno = ENXIO;
2798 		return (-1);
2799 	}
2800 
2801 	*pci = &cpu_info;
2802 	return (0);
2803 }
2804 
2805 int
2806 pmc_detach(pmc_id_t pmc, pid_t pid)
2807 {
2808 	struct pmc_op_pmcattach pmc_detach_args;
2809 
2810 	pmc_detach_args.pm_pmc = pmc;
2811 	pmc_detach_args.pm_pid = pid;
2812 	return (PMC_CALL(PMCDETACH, &pmc_detach_args));
2813 }
2814 
2815 int
2816 pmc_disable(int cpu, int pmc)
2817 {
2818 	struct pmc_op_pmcadmin ssa;
2819 
2820 	ssa.pm_cpu = cpu;
2821 	ssa.pm_pmc = pmc;
2822 	ssa.pm_state = PMC_STATE_DISABLED;
2823 	return (PMC_CALL(PMCADMIN, &ssa));
2824 }
2825 
2826 int
2827 pmc_enable(int cpu, int pmc)
2828 {
2829 	struct pmc_op_pmcadmin ssa;
2830 
2831 	ssa.pm_cpu = cpu;
2832 	ssa.pm_pmc = pmc;
2833 	ssa.pm_state = PMC_STATE_FREE;
2834 	return (PMC_CALL(PMCADMIN, &ssa));
2835 }
2836 
2837 /*
2838  * Return a list of events known to a given PMC class.  'cl' is the
2839  * PMC class identifier, 'eventnames' is the returned list of 'const
2840  * char *' pointers pointing to the names of the events. 'nevents' is
2841  * the number of event name pointers returned.
2842  *
2843  * The space for 'eventnames' is allocated using malloc(3).  The caller
2844  * is responsible for freeing this space when done.
2845  */
2846 int
2847 pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
2848     int *nevents)
2849 {
2850 	int count;
2851 	const char **names;
2852 	const struct pmc_event_descr *ev;
2853 
2854 	switch (cl)
2855 	{
2856 	case PMC_CLASS_IAF:
2857 		ev = iaf_event_table;
2858 		count = PMC_EVENT_TABLE_SIZE(iaf);
2859 		break;
2860 	case PMC_CLASS_IAP:
2861 		/*
2862 		 * Return the most appropriate set of event name
2863 		 * spellings for the current CPU.
2864 		 */
2865 		switch (cpu_info.pm_cputype) {
2866 		default:
2867 		case PMC_CPU_INTEL_ATOM:
2868 			ev = atom_event_table;
2869 			count = PMC_EVENT_TABLE_SIZE(atom);
2870 			break;
2871 		case PMC_CPU_INTEL_ATOM_SILVERMONT:
2872 			ev = atom_silvermont_event_table;
2873 			count = PMC_EVENT_TABLE_SIZE(atom_silvermont);
2874 			break;
2875 		case PMC_CPU_INTEL_CORE:
2876 			ev = core_event_table;
2877 			count = PMC_EVENT_TABLE_SIZE(core);
2878 			break;
2879 		case PMC_CPU_INTEL_CORE2:
2880 		case PMC_CPU_INTEL_CORE2EXTREME:
2881 			ev = core2_event_table;
2882 			count = PMC_EVENT_TABLE_SIZE(core2);
2883 			break;
2884 		case PMC_CPU_INTEL_COREI7:
2885 			ev = corei7_event_table;
2886 			count = PMC_EVENT_TABLE_SIZE(corei7);
2887 			break;
2888 		case PMC_CPU_INTEL_NEHALEM_EX:
2889 			ev = nehalem_ex_event_table;
2890 			count = PMC_EVENT_TABLE_SIZE(nehalem_ex);
2891 			break;
2892 		case PMC_CPU_INTEL_HASWELL:
2893 			ev = haswell_event_table;
2894 			count = PMC_EVENT_TABLE_SIZE(haswell);
2895 			break;
2896 		case PMC_CPU_INTEL_HASWELL_XEON:
2897 			ev = haswell_xeon_event_table;
2898 			count = PMC_EVENT_TABLE_SIZE(haswell_xeon);
2899 			break;
2900 		case PMC_CPU_INTEL_IVYBRIDGE:
2901 			ev = ivybridge_event_table;
2902 			count = PMC_EVENT_TABLE_SIZE(ivybridge);
2903 			break;
2904 		case PMC_CPU_INTEL_IVYBRIDGE_XEON:
2905 			ev = ivybridge_xeon_event_table;
2906 			count = PMC_EVENT_TABLE_SIZE(ivybridge_xeon);
2907 			break;
2908 		case PMC_CPU_INTEL_SANDYBRIDGE:
2909 			ev = sandybridge_event_table;
2910 			count = PMC_EVENT_TABLE_SIZE(sandybridge);
2911 			break;
2912 		case PMC_CPU_INTEL_SANDYBRIDGE_XEON:
2913 			ev = sandybridge_xeon_event_table;
2914 			count = PMC_EVENT_TABLE_SIZE(sandybridge_xeon);
2915 			break;
2916 		case PMC_CPU_INTEL_WESTMERE:
2917 			ev = westmere_event_table;
2918 			count = PMC_EVENT_TABLE_SIZE(westmere);
2919 			break;
2920 		case PMC_CPU_INTEL_WESTMERE_EX:
2921 			ev = westmere_ex_event_table;
2922 			count = PMC_EVENT_TABLE_SIZE(westmere_ex);
2923 			break;
2924 		}
2925 		break;
2926 	case PMC_CLASS_UCF:
2927 		ev = ucf_event_table;
2928 		count = PMC_EVENT_TABLE_SIZE(ucf);
2929 		break;
2930 	case PMC_CLASS_UCP:
2931 		/*
2932 		 * Return the most appropriate set of event name
2933 		 * spellings for the current CPU.
2934 		 */
2935 		switch (cpu_info.pm_cputype) {
2936 		default:
2937 		case PMC_CPU_INTEL_COREI7:
2938 			ev = corei7uc_event_table;
2939 			count = PMC_EVENT_TABLE_SIZE(corei7uc);
2940 			break;
2941 		case PMC_CPU_INTEL_HASWELL:
2942 			ev = haswelluc_event_table;
2943 			count = PMC_EVENT_TABLE_SIZE(haswelluc);
2944 			break;
2945 		case PMC_CPU_INTEL_SANDYBRIDGE:
2946 			ev = sandybridgeuc_event_table;
2947 			count = PMC_EVENT_TABLE_SIZE(sandybridgeuc);
2948 			break;
2949 		case PMC_CPU_INTEL_WESTMERE:
2950 			ev = westmereuc_event_table;
2951 			count = PMC_EVENT_TABLE_SIZE(westmereuc);
2952 			break;
2953 		}
2954 		break;
2955 	case PMC_CLASS_TSC:
2956 		ev = tsc_event_table;
2957 		count = PMC_EVENT_TABLE_SIZE(tsc);
2958 		break;
2959 	case PMC_CLASS_K7:
2960 		ev = k7_event_table;
2961 		count = PMC_EVENT_TABLE_SIZE(k7);
2962 		break;
2963 	case PMC_CLASS_K8:
2964 		ev = k8_event_table;
2965 		count = PMC_EVENT_TABLE_SIZE(k8);
2966 		break;
2967 	case PMC_CLASS_P4:
2968 		ev = p4_event_table;
2969 		count = PMC_EVENT_TABLE_SIZE(p4);
2970 		break;
2971 	case PMC_CLASS_P5:
2972 		ev = p5_event_table;
2973 		count = PMC_EVENT_TABLE_SIZE(p5);
2974 		break;
2975 	case PMC_CLASS_P6:
2976 		ev = p6_event_table;
2977 		count = PMC_EVENT_TABLE_SIZE(p6);
2978 		break;
2979 	case PMC_CLASS_XSCALE:
2980 		ev = xscale_event_table;
2981 		count = PMC_EVENT_TABLE_SIZE(xscale);
2982 		break;
2983 	case PMC_CLASS_ARMV7:
2984 		ev = armv7_event_table;
2985 		count = PMC_EVENT_TABLE_SIZE(armv7);
2986 		break;
2987 	case PMC_CLASS_ARMV8:
2988 		switch (cpu_info.pm_cputype) {
2989 		default:
2990 		case PMC_CPU_ARMV8_CORTEX_A53:
2991 			ev = cortex_a53_event_table;
2992 			count = PMC_EVENT_TABLE_SIZE(cortex_a53);
2993 			break;
2994 		case PMC_CPU_ARMV8_CORTEX_A57:
2995 			ev = cortex_a57_event_table;
2996 			count = PMC_EVENT_TABLE_SIZE(cortex_a57);
2997 			break;
2998 		}
2999 		break;
3000 	case PMC_CLASS_MIPS24K:
3001 		ev = mips24k_event_table;
3002 		count = PMC_EVENT_TABLE_SIZE(mips24k);
3003 		break;
3004 	case PMC_CLASS_MIPS74K:
3005 		ev = mips74k_event_table;
3006 		count = PMC_EVENT_TABLE_SIZE(mips74k);
3007 		break;
3008 	case PMC_CLASS_OCTEON:
3009 		ev = octeon_event_table;
3010 		count = PMC_EVENT_TABLE_SIZE(octeon);
3011 		break;
3012 	case PMC_CLASS_PPC7450:
3013 		ev = ppc7450_event_table;
3014 		count = PMC_EVENT_TABLE_SIZE(ppc7450);
3015 		break;
3016 	case PMC_CLASS_PPC970:
3017 		ev = ppc970_event_table;
3018 		count = PMC_EVENT_TABLE_SIZE(ppc970);
3019 		break;
3020 	case PMC_CLASS_E500:
3021 		ev = e500_event_table;
3022 		count = PMC_EVENT_TABLE_SIZE(e500);
3023 		break;
3024 	case PMC_CLASS_SOFT:
3025 		ev = soft_event_table;
3026 		count = soft_event_info.pm_nevent;
3027 		break;
3028 	default:
3029 		errno = EINVAL;
3030 		return (-1);
3031 	}
3032 
3033 	if ((names = malloc(count * sizeof(const char *))) == NULL)
3034 		return (-1);
3035 
3036 	*eventnames = names;
3037 	*nevents = count;
3038 
3039 	for (;count--; ev++, names++)
3040 		*names = ev->pm_ev_name;
3041 
3042 	return (0);
3043 }
3044 
3045 int
3046 pmc_flush_logfile(void)
3047 {
3048 	return (PMC_CALL(FLUSHLOG,0));
3049 }
3050 
3051 int
3052 pmc_close_logfile(void)
3053 {
3054 	return (PMC_CALL(CLOSELOG,0));
3055 }
3056 
3057 int
3058 pmc_get_driver_stats(struct pmc_driverstats *ds)
3059 {
3060 	struct pmc_op_getdriverstats gms;
3061 
3062 	if (PMC_CALL(GETDRIVERSTATS, &gms) < 0)
3063 		return (-1);
3064 
3065 	/* copy out fields in the current userland<->library interface */
3066 	ds->pm_intr_ignored    = gms.pm_intr_ignored;
3067 	ds->pm_intr_processed  = gms.pm_intr_processed;
3068 	ds->pm_intr_bufferfull = gms.pm_intr_bufferfull;
3069 	ds->pm_syscalls        = gms.pm_syscalls;
3070 	ds->pm_syscall_errors  = gms.pm_syscall_errors;
3071 	ds->pm_buffer_requests = gms.pm_buffer_requests;
3072 	ds->pm_buffer_requests_failed = gms.pm_buffer_requests_failed;
3073 	ds->pm_log_sweeps      = gms.pm_log_sweeps;
3074 	return (0);
3075 }
3076 
3077 int
3078 pmc_get_msr(pmc_id_t pmc, uint32_t *msr)
3079 {
3080 	struct pmc_op_getmsr gm;
3081 
3082 	gm.pm_pmcid = pmc;
3083 	if (PMC_CALL(PMCGETMSR, &gm) < 0)
3084 		return (-1);
3085 	*msr = gm.pm_msr;
3086 	return (0);
3087 }
3088 
3089 int
3090 pmc_init(void)
3091 {
3092 	int error, pmc_mod_id;
3093 	unsigned int n;
3094 	uint32_t abi_version;
3095 	struct module_stat pmc_modstat;
3096 	struct pmc_op_getcpuinfo op_cpu_info;
3097 #if defined(__amd64__) || defined(__i386__)
3098 	int cpu_has_iaf_counters;
3099 	unsigned int t;
3100 #endif
3101 
3102 	if (pmc_syscall != -1) /* already inited */
3103 		return (0);
3104 
3105 	/* retrieve the system call number from the KLD */
3106 	if ((pmc_mod_id = modfind(PMC_MODULE_NAME)) < 0)
3107 		return (-1);
3108 
3109 	pmc_modstat.version = sizeof(struct module_stat);
3110 	if ((error = modstat(pmc_mod_id, &pmc_modstat)) < 0)
3111 		return (-1);
3112 
3113 	pmc_syscall = pmc_modstat.data.intval;
3114 
3115 	/* check the kernel module's ABI against our compiled-in version */
3116 	abi_version = PMC_VERSION;
3117 	if (PMC_CALL(GETMODULEVERSION, &abi_version) < 0)
3118 		return (pmc_syscall = -1);
3119 
3120 	/* ignore patch & minor numbers for the comparision */
3121 	if ((abi_version & 0xFF000000) != (PMC_VERSION & 0xFF000000)) {
3122 		errno  = EPROGMISMATCH;
3123 		return (pmc_syscall = -1);
3124 	}
3125 
3126 	if (PMC_CALL(GETCPUINFO, &op_cpu_info) < 0)
3127 		return (pmc_syscall = -1);
3128 
3129 	cpu_info.pm_cputype = op_cpu_info.pm_cputype;
3130 	cpu_info.pm_ncpu    = op_cpu_info.pm_ncpu;
3131 	cpu_info.pm_npmc    = op_cpu_info.pm_npmc;
3132 	cpu_info.pm_nclass  = op_cpu_info.pm_nclass;
3133 	for (n = 0; n < cpu_info.pm_nclass; n++)
3134 		cpu_info.pm_classes[n] = op_cpu_info.pm_classes[n];
3135 
3136 	pmc_class_table = malloc(PMC_CLASS_TABLE_SIZE *
3137 	    sizeof(struct pmc_class_descr *));
3138 
3139 	if (pmc_class_table == NULL)
3140 		return (-1);
3141 
3142 	for (n = 0; n < PMC_CLASS_TABLE_SIZE; n++)
3143 		pmc_class_table[n] = NULL;
3144 
3145 	/*
3146 	 * Get soft events list.
3147 	 */
3148 	soft_event_info.pm_class = PMC_CLASS_SOFT;
3149 	if (PMC_CALL(GETDYNEVENTINFO, &soft_event_info) < 0)
3150 		return (pmc_syscall = -1);
3151 
3152 	/* Map soft events to static list. */
3153 	for (n = 0; n < soft_event_info.pm_nevent; n++) {
3154 		soft_event_table[n].pm_ev_name =
3155 		    soft_event_info.pm_events[n].pm_ev_name;
3156 		soft_event_table[n].pm_ev_code =
3157 		    soft_event_info.pm_events[n].pm_ev_code;
3158 	}
3159 	soft_class_table_descr.pm_evc_event_table_size = \
3160 	    soft_event_info.pm_nevent;
3161 	soft_class_table_descr.pm_evc_event_table = \
3162 	    soft_event_table;
3163 
3164 	/*
3165 	 * Fill in the class table.
3166 	 */
3167 	n = 0;
3168 
3169 	/* Fill soft events information. */
3170 	pmc_class_table[n++] = &soft_class_table_descr;
3171 #if defined(__amd64__) || defined(__i386__)
3172 	if (cpu_info.pm_cputype != PMC_CPU_GENERIC)
3173 		pmc_class_table[n++] = &tsc_class_table_descr;
3174 
3175 	/*
3176  	 * Check if this CPU has fixed function counters.
3177 	 */
3178 	cpu_has_iaf_counters = 0;
3179 	for (t = 0; t < cpu_info.pm_nclass; t++)
3180 		if (cpu_info.pm_classes[t].pm_class == PMC_CLASS_IAF &&
3181 		    cpu_info.pm_classes[t].pm_num > 0)
3182 			cpu_has_iaf_counters = 1;
3183 #endif
3184 
3185 #define	PMC_MDEP_INIT(C) do {					\
3186 		pmc_mdep_event_aliases    = C##_aliases;	\
3187 		pmc_mdep_class_list  = C##_pmc_classes;		\
3188 		pmc_mdep_class_list_size =			\
3189 		    PMC_TABLE_SIZE(C##_pmc_classes);		\
3190 	} while (0)
3191 
3192 #define	PMC_MDEP_INIT_INTEL_V2(C) do {					\
3193 		PMC_MDEP_INIT(C);					\
3194 		pmc_class_table[n++] = &iaf_class_table_descr;		\
3195 		if (!cpu_has_iaf_counters) 				\
3196 			pmc_mdep_event_aliases =			\
3197 				C##_aliases_without_iaf;		\
3198 		pmc_class_table[n] = &C##_class_table_descr;		\
3199 	} while (0)
3200 
3201 	/* Configure the event name parser. */
3202 	switch (cpu_info.pm_cputype) {
3203 #if defined(__i386__)
3204 	case PMC_CPU_AMD_K7:
3205 		PMC_MDEP_INIT(k7);
3206 		pmc_class_table[n] = &k7_class_table_descr;
3207 		break;
3208 	case PMC_CPU_INTEL_P5:
3209 		PMC_MDEP_INIT(p5);
3210 		pmc_class_table[n]  = &p5_class_table_descr;
3211 		break;
3212 	case PMC_CPU_INTEL_P6:		/* P6 ... Pentium M CPUs have */
3213 	case PMC_CPU_INTEL_PII:		/* similar PMCs. */
3214 	case PMC_CPU_INTEL_PIII:
3215 	case PMC_CPU_INTEL_PM:
3216 		PMC_MDEP_INIT(p6);
3217 		pmc_class_table[n] = &p6_class_table_descr;
3218 		break;
3219 #endif
3220 #if defined(__amd64__) || defined(__i386__)
3221 	case PMC_CPU_AMD_K8:
3222 		PMC_MDEP_INIT(k8);
3223 		pmc_class_table[n] = &k8_class_table_descr;
3224 		break;
3225 	case PMC_CPU_INTEL_ATOM:
3226 		PMC_MDEP_INIT_INTEL_V2(atom);
3227 		break;
3228 	case PMC_CPU_INTEL_ATOM_SILVERMONT:
3229 		PMC_MDEP_INIT_INTEL_V2(atom_silvermont);
3230 		break;
3231 	case PMC_CPU_INTEL_CORE:
3232 		PMC_MDEP_INIT(core);
3233 		pmc_class_table[n] = &core_class_table_descr;
3234 		break;
3235 	case PMC_CPU_INTEL_CORE2:
3236 	case PMC_CPU_INTEL_CORE2EXTREME:
3237 		PMC_MDEP_INIT_INTEL_V2(core2);
3238 		break;
3239 	case PMC_CPU_INTEL_COREI7:
3240 		pmc_class_table[n++] = &ucf_class_table_descr;
3241 		pmc_class_table[n++] = &corei7uc_class_table_descr;
3242 		PMC_MDEP_INIT_INTEL_V2(corei7);
3243 		break;
3244 	case PMC_CPU_INTEL_NEHALEM_EX:
3245 		PMC_MDEP_INIT_INTEL_V2(nehalem_ex);
3246 		break;
3247 	case PMC_CPU_INTEL_HASWELL:
3248 		pmc_class_table[n++] = &ucf_class_table_descr;
3249 		pmc_class_table[n++] = &haswelluc_class_table_descr;
3250 		PMC_MDEP_INIT_INTEL_V2(haswell);
3251 		break;
3252 	case PMC_CPU_INTEL_HASWELL_XEON:
3253 		PMC_MDEP_INIT_INTEL_V2(haswell_xeon);
3254 		break;
3255 	case PMC_CPU_INTEL_IVYBRIDGE:
3256 		PMC_MDEP_INIT_INTEL_V2(ivybridge);
3257 		break;
3258 	case PMC_CPU_INTEL_IVYBRIDGE_XEON:
3259 		PMC_MDEP_INIT_INTEL_V2(ivybridge_xeon);
3260 		break;
3261 	case PMC_CPU_INTEL_SANDYBRIDGE:
3262 		pmc_class_table[n++] = &ucf_class_table_descr;
3263 		pmc_class_table[n++] = &sandybridgeuc_class_table_descr;
3264 		PMC_MDEP_INIT_INTEL_V2(sandybridge);
3265 		break;
3266 	case PMC_CPU_INTEL_SANDYBRIDGE_XEON:
3267 		PMC_MDEP_INIT_INTEL_V2(sandybridge_xeon);
3268 		break;
3269 	case PMC_CPU_INTEL_WESTMERE:
3270 		pmc_class_table[n++] = &ucf_class_table_descr;
3271 		pmc_class_table[n++] = &westmereuc_class_table_descr;
3272 		PMC_MDEP_INIT_INTEL_V2(westmere);
3273 		break;
3274 	case PMC_CPU_INTEL_WESTMERE_EX:
3275 		PMC_MDEP_INIT_INTEL_V2(westmere_ex);
3276 		break;
3277 	case PMC_CPU_INTEL_PIV:
3278 		PMC_MDEP_INIT(p4);
3279 		pmc_class_table[n] = &p4_class_table_descr;
3280 		break;
3281 #endif
3282 	case PMC_CPU_GENERIC:
3283 		PMC_MDEP_INIT(generic);
3284 		break;
3285 #if defined(__arm__)
3286 #if defined(__XSCALE__)
3287 	case PMC_CPU_INTEL_XSCALE:
3288 		PMC_MDEP_INIT(xscale);
3289 		pmc_class_table[n] = &xscale_class_table_descr;
3290 		break;
3291 #endif
3292 	case PMC_CPU_ARMV7:
3293 		PMC_MDEP_INIT(armv7);
3294 		pmc_class_table[n] = &armv7_class_table_descr;
3295 		break;
3296 #endif
3297 #if defined(__aarch64__)
3298 	case PMC_CPU_ARMV8_CORTEX_A53:
3299 		PMC_MDEP_INIT(cortex_a53);
3300 		pmc_class_table[n] = &cortex_a53_class_table_descr;
3301 		break;
3302 	case PMC_CPU_ARMV8_CORTEX_A57:
3303 		PMC_MDEP_INIT(cortex_a57);
3304 		pmc_class_table[n] = &cortex_a57_class_table_descr;
3305 		break;
3306 #endif
3307 #if defined(__mips__)
3308 	case PMC_CPU_MIPS_24K:
3309 		PMC_MDEP_INIT(mips24k);
3310 		pmc_class_table[n] = &mips24k_class_table_descr;
3311 		break;
3312 	case PMC_CPU_MIPS_74K:
3313 		PMC_MDEP_INIT(mips74k);
3314 		pmc_class_table[n] = &mips74k_class_table_descr;
3315 		break;
3316 	case PMC_CPU_MIPS_OCTEON:
3317 		PMC_MDEP_INIT(octeon);
3318 		pmc_class_table[n] = &octeon_class_table_descr;
3319 		break;
3320 #endif /* __mips__ */
3321 #if defined(__powerpc__)
3322 	case PMC_CPU_PPC_7450:
3323 		PMC_MDEP_INIT(ppc7450);
3324 		pmc_class_table[n] = &ppc7450_class_table_descr;
3325 		break;
3326 	case PMC_CPU_PPC_970:
3327 		PMC_MDEP_INIT(ppc970);
3328 		pmc_class_table[n] = &ppc970_class_table_descr;
3329 		break;
3330 	case PMC_CPU_PPC_E500:
3331 		PMC_MDEP_INIT(e500);
3332 		pmc_class_table[n] = &e500_class_table_descr;
3333 		break;
3334 #endif
3335 	default:
3336 		/*
3337 		 * Some kind of CPU this version of the library knows nothing
3338 		 * about.  This shouldn't happen since the abi version check
3339 		 * should have caught this.
3340 		 */
3341 		errno = ENXIO;
3342 		return (pmc_syscall = -1);
3343 	}
3344 
3345 	return (0);
3346 }
3347 
3348 const char *
3349 pmc_name_of_capability(enum pmc_caps cap)
3350 {
3351 	int i;
3352 
3353 	/*
3354 	 * 'cap' should have a single bit set and should be in
3355 	 * range.
3356 	 */
3357 	if ((cap & (cap - 1)) || cap < PMC_CAP_FIRST ||
3358 	    cap > PMC_CAP_LAST) {
3359 		errno = EINVAL;
3360 		return (NULL);
3361 	}
3362 
3363 	i = ffs(cap);
3364 	return (pmc_capability_names[i - 1]);
3365 }
3366 
3367 const char *
3368 pmc_name_of_class(enum pmc_class pc)
3369 {
3370 	size_t n;
3371 
3372 	for (n = 0; n < PMC_TABLE_SIZE(pmc_class_names); n++)
3373 		if (pc == pmc_class_names[n].pm_class)
3374 			return (pmc_class_names[n].pm_name);
3375 
3376 	errno = EINVAL;
3377 	return (NULL);
3378 }
3379 
3380 const char *
3381 pmc_name_of_cputype(enum pmc_cputype cp)
3382 {
3383 	size_t n;
3384 
3385 	for (n = 0; n < PMC_TABLE_SIZE(pmc_cputype_names); n++)
3386 		if (cp == pmc_cputype_names[n].pm_cputype)
3387 			return (pmc_cputype_names[n].pm_name);
3388 
3389 	errno = EINVAL;
3390 	return (NULL);
3391 }
3392 
3393 const char *
3394 pmc_name_of_disposition(enum pmc_disp pd)
3395 {
3396 	if ((int) pd >= PMC_DISP_FIRST &&
3397 	    pd <= PMC_DISP_LAST)
3398 		return (pmc_disposition_names[pd]);
3399 
3400 	errno = EINVAL;
3401 	return (NULL);
3402 }
3403 
3404 const char *
3405 _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
3406 {
3407 	const struct pmc_event_descr *ev, *evfence;
3408 
3409 	ev = evfence = NULL;
3410 	if (pe >= PMC_EV_IAF_FIRST && pe <= PMC_EV_IAF_LAST) {
3411 		ev = iaf_event_table;
3412 		evfence = iaf_event_table + PMC_EVENT_TABLE_SIZE(iaf);
3413 	} else if (pe >= PMC_EV_IAP_FIRST && pe <= PMC_EV_IAP_LAST) {
3414 		switch (cpu) {
3415 		case PMC_CPU_INTEL_ATOM:
3416 			ev = atom_event_table;
3417 			evfence = atom_event_table + PMC_EVENT_TABLE_SIZE(atom);
3418 			break;
3419 		case PMC_CPU_INTEL_ATOM_SILVERMONT:
3420 			ev = atom_silvermont_event_table;
3421 			evfence = atom_silvermont_event_table +
3422 			    PMC_EVENT_TABLE_SIZE(atom_silvermont);
3423 			break;
3424 		case PMC_CPU_INTEL_CORE:
3425 			ev = core_event_table;
3426 			evfence = core_event_table + PMC_EVENT_TABLE_SIZE(core);
3427 			break;
3428 		case PMC_CPU_INTEL_CORE2:
3429 		case PMC_CPU_INTEL_CORE2EXTREME:
3430 			ev = core2_event_table;
3431 			evfence = core2_event_table + PMC_EVENT_TABLE_SIZE(core2);
3432 			break;
3433 		case PMC_CPU_INTEL_COREI7:
3434 			ev = corei7_event_table;
3435 			evfence = corei7_event_table + PMC_EVENT_TABLE_SIZE(corei7);
3436 			break;
3437 		case PMC_CPU_INTEL_NEHALEM_EX:
3438 			ev = nehalem_ex_event_table;
3439 			evfence = nehalem_ex_event_table +
3440 			    PMC_EVENT_TABLE_SIZE(nehalem_ex);
3441 			break;
3442 		case PMC_CPU_INTEL_HASWELL:
3443 			ev = haswell_event_table;
3444 			evfence = haswell_event_table + PMC_EVENT_TABLE_SIZE(haswell);
3445 			break;
3446 		case PMC_CPU_INTEL_HASWELL_XEON:
3447 			ev = haswell_xeon_event_table;
3448 			evfence = haswell_xeon_event_table + PMC_EVENT_TABLE_SIZE(haswell_xeon);
3449 			break;
3450 
3451 		case PMC_CPU_INTEL_IVYBRIDGE:
3452 			ev = ivybridge_event_table;
3453 			evfence = ivybridge_event_table + PMC_EVENT_TABLE_SIZE(ivybridge);
3454 			break;
3455 		case PMC_CPU_INTEL_IVYBRIDGE_XEON:
3456 			ev = ivybridge_xeon_event_table;
3457 			evfence = ivybridge_xeon_event_table + PMC_EVENT_TABLE_SIZE(ivybridge_xeon);
3458 			break;
3459 		case PMC_CPU_INTEL_SANDYBRIDGE:
3460 			ev = sandybridge_event_table;
3461 			evfence = sandybridge_event_table + PMC_EVENT_TABLE_SIZE(sandybridge);
3462 			break;
3463 		case PMC_CPU_INTEL_SANDYBRIDGE_XEON:
3464 			ev = sandybridge_xeon_event_table;
3465 			evfence = sandybridge_xeon_event_table + PMC_EVENT_TABLE_SIZE(sandybridge_xeon);
3466 			break;
3467 		case PMC_CPU_INTEL_WESTMERE:
3468 			ev = westmere_event_table;
3469 			evfence = westmere_event_table + PMC_EVENT_TABLE_SIZE(westmere);
3470 			break;
3471 		case PMC_CPU_INTEL_WESTMERE_EX:
3472 			ev = westmere_ex_event_table;
3473 			evfence = westmere_ex_event_table +
3474 			    PMC_EVENT_TABLE_SIZE(westmere_ex);
3475 			break;
3476 		default:	/* Unknown CPU type. */
3477 			break;
3478 		}
3479 	} else if (pe >= PMC_EV_UCF_FIRST && pe <= PMC_EV_UCF_LAST) {
3480 		ev = ucf_event_table;
3481 		evfence = ucf_event_table + PMC_EVENT_TABLE_SIZE(ucf);
3482 	} else if (pe >= PMC_EV_UCP_FIRST && pe <= PMC_EV_UCP_LAST) {
3483 		switch (cpu) {
3484 		case PMC_CPU_INTEL_COREI7:
3485 			ev = corei7uc_event_table;
3486 			evfence = corei7uc_event_table + PMC_EVENT_TABLE_SIZE(corei7uc);
3487 			break;
3488 		case PMC_CPU_INTEL_SANDYBRIDGE:
3489 			ev = sandybridgeuc_event_table;
3490 			evfence = sandybridgeuc_event_table + PMC_EVENT_TABLE_SIZE(sandybridgeuc);
3491 			break;
3492 		case PMC_CPU_INTEL_WESTMERE:
3493 			ev = westmereuc_event_table;
3494 			evfence = westmereuc_event_table + PMC_EVENT_TABLE_SIZE(westmereuc);
3495 			break;
3496 		default:	/* Unknown CPU type. */
3497 			break;
3498 		}
3499 	} else if (pe >= PMC_EV_K7_FIRST && pe <= PMC_EV_K7_LAST) {
3500 		ev = k7_event_table;
3501 		evfence = k7_event_table + PMC_EVENT_TABLE_SIZE(k7);
3502 	} else if (pe >= PMC_EV_K8_FIRST && pe <= PMC_EV_K8_LAST) {
3503 		ev = k8_event_table;
3504 		evfence = k8_event_table + PMC_EVENT_TABLE_SIZE(k8);
3505 	} else if (pe >= PMC_EV_P4_FIRST && pe <= PMC_EV_P4_LAST) {
3506 		ev = p4_event_table;
3507 		evfence = p4_event_table + PMC_EVENT_TABLE_SIZE(p4);
3508 	} else if (pe >= PMC_EV_P5_FIRST && pe <= PMC_EV_P5_LAST) {
3509 		ev = p5_event_table;
3510 		evfence = p5_event_table + PMC_EVENT_TABLE_SIZE(p5);
3511 	} else if (pe >= PMC_EV_P6_FIRST && pe <= PMC_EV_P6_LAST) {
3512 		ev = p6_event_table;
3513 		evfence = p6_event_table + PMC_EVENT_TABLE_SIZE(p6);
3514 	} else if (pe >= PMC_EV_XSCALE_FIRST && pe <= PMC_EV_XSCALE_LAST) {
3515 		ev = xscale_event_table;
3516 		evfence = xscale_event_table + PMC_EVENT_TABLE_SIZE(xscale);
3517 	} else if (pe >= PMC_EV_ARMV7_FIRST && pe <= PMC_EV_ARMV7_LAST) {
3518 		ev = armv7_event_table;
3519 		evfence = armv7_event_table + PMC_EVENT_TABLE_SIZE(armv7);
3520 	} else if (pe >= PMC_EV_ARMV8_FIRST && pe <= PMC_EV_ARMV8_LAST) {
3521 		switch (cpu) {
3522 		case PMC_CPU_ARMV8_CORTEX_A53:
3523 			ev = cortex_a53_event_table;
3524 			evfence = cortex_a53_event_table + PMC_EVENT_TABLE_SIZE(cortex_a53);
3525 			break;
3526 		case PMC_CPU_ARMV8_CORTEX_A57:
3527 			ev = cortex_a57_event_table;
3528 			evfence = cortex_a57_event_table + PMC_EVENT_TABLE_SIZE(cortex_a57);
3529 			break;
3530 		default:	/* Unknown CPU type. */
3531 			break;
3532 		}
3533 	} else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) {
3534 		ev = mips24k_event_table;
3535 		evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k);
3536 	} else if (pe >= PMC_EV_MIPS74K_FIRST && pe <= PMC_EV_MIPS74K_LAST) {
3537 		ev = mips74k_event_table;
3538 		evfence = mips74k_event_table + PMC_EVENT_TABLE_SIZE(mips74k);
3539 	} else if (pe >= PMC_EV_OCTEON_FIRST && pe <= PMC_EV_OCTEON_LAST) {
3540 		ev = octeon_event_table;
3541 		evfence = octeon_event_table + PMC_EVENT_TABLE_SIZE(octeon);
3542 	} else if (pe >= PMC_EV_PPC7450_FIRST && pe <= PMC_EV_PPC7450_LAST) {
3543 		ev = ppc7450_event_table;
3544 		evfence = ppc7450_event_table + PMC_EVENT_TABLE_SIZE(ppc7450);
3545 	} else if (pe >= PMC_EV_PPC970_FIRST && pe <= PMC_EV_PPC970_LAST) {
3546 		ev = ppc970_event_table;
3547 		evfence = ppc970_event_table + PMC_EVENT_TABLE_SIZE(ppc970);
3548 	} else if (pe >= PMC_EV_E500_FIRST && pe <= PMC_EV_E500_LAST) {
3549 		ev = e500_event_table;
3550 		evfence = e500_event_table + PMC_EVENT_TABLE_SIZE(e500);
3551 	} else if (pe == PMC_EV_TSC_TSC) {
3552 		ev = tsc_event_table;
3553 		evfence = tsc_event_table + PMC_EVENT_TABLE_SIZE(tsc);
3554 	} else if ((int)pe >= PMC_EV_SOFT_FIRST && (int)pe <= PMC_EV_SOFT_LAST) {
3555 		ev = soft_event_table;
3556 		evfence = soft_event_table + soft_event_info.pm_nevent;
3557 	}
3558 
3559 	for (; ev != evfence; ev++)
3560 		if (pe == ev->pm_ev_code)
3561 			return (ev->pm_ev_name);
3562 
3563 	return (NULL);
3564 }
3565 
3566 const char *
3567 pmc_name_of_event(enum pmc_event pe)
3568 {
3569 	const char *n;
3570 
3571 	if ((n = _pmc_name_of_event(pe, cpu_info.pm_cputype)) != NULL)
3572 		return (n);
3573 
3574 	errno = EINVAL;
3575 	return (NULL);
3576 }
3577 
3578 const char *
3579 pmc_name_of_mode(enum pmc_mode pm)
3580 {
3581 	if ((int) pm >= PMC_MODE_FIRST &&
3582 	    pm <= PMC_MODE_LAST)
3583 		return (pmc_mode_names[pm]);
3584 
3585 	errno = EINVAL;
3586 	return (NULL);
3587 }
3588 
3589 const char *
3590 pmc_name_of_state(enum pmc_state ps)
3591 {
3592 	if ((int) ps >= PMC_STATE_FIRST &&
3593 	    ps <= PMC_STATE_LAST)
3594 		return (pmc_state_names[ps]);
3595 
3596 	errno = EINVAL;
3597 	return (NULL);
3598 }
3599 
3600 int
3601 pmc_ncpu(void)
3602 {
3603 	if (pmc_syscall == -1) {
3604 		errno = ENXIO;
3605 		return (-1);
3606 	}
3607 
3608 	return (cpu_info.pm_ncpu);
3609 }
3610 
3611 int
3612 pmc_npmc(int cpu)
3613 {
3614 	if (pmc_syscall == -1) {
3615 		errno = ENXIO;
3616 		return (-1);
3617 	}
3618 
3619 	if (cpu < 0 || cpu >= (int) cpu_info.pm_ncpu) {
3620 		errno = EINVAL;
3621 		return (-1);
3622 	}
3623 
3624 	return (cpu_info.pm_npmc);
3625 }
3626 
3627 int
3628 pmc_pmcinfo(int cpu, struct pmc_pmcinfo **ppmci)
3629 {
3630 	int nbytes, npmc;
3631 	struct pmc_op_getpmcinfo *pmci;
3632 
3633 	if ((npmc = pmc_npmc(cpu)) < 0)
3634 		return (-1);
3635 
3636 	nbytes = sizeof(struct pmc_op_getpmcinfo) +
3637 	    npmc * sizeof(struct pmc_info);
3638 
3639 	if ((pmci = calloc(1, nbytes)) == NULL)
3640 		return (-1);
3641 
3642 	pmci->pm_cpu  = cpu;
3643 
3644 	if (PMC_CALL(GETPMCINFO, pmci) < 0) {
3645 		free(pmci);
3646 		return (-1);
3647 	}
3648 
3649 	/* kernel<->library, library<->userland interfaces are identical */
3650 	*ppmci = (struct pmc_pmcinfo *) pmci;
3651 	return (0);
3652 }
3653 
3654 int
3655 pmc_read(pmc_id_t pmc, pmc_value_t *value)
3656 {
3657 	struct pmc_op_pmcrw pmc_read_op;
3658 
3659 	pmc_read_op.pm_pmcid = pmc;
3660 	pmc_read_op.pm_flags = PMC_F_OLDVALUE;
3661 	pmc_read_op.pm_value = -1;
3662 
3663 	if (PMC_CALL(PMCRW, &pmc_read_op) < 0)
3664 		return (-1);
3665 
3666 	*value = pmc_read_op.pm_value;
3667 	return (0);
3668 }
3669 
3670 int
3671 pmc_release(pmc_id_t pmc)
3672 {
3673 	struct pmc_op_simple	pmc_release_args;
3674 
3675 	pmc_release_args.pm_pmcid = pmc;
3676 	return (PMC_CALL(PMCRELEASE, &pmc_release_args));
3677 }
3678 
3679 int
3680 pmc_rw(pmc_id_t pmc, pmc_value_t newvalue, pmc_value_t *oldvaluep)
3681 {
3682 	struct pmc_op_pmcrw pmc_rw_op;
3683 
3684 	pmc_rw_op.pm_pmcid = pmc;
3685 	pmc_rw_op.pm_flags = PMC_F_NEWVALUE | PMC_F_OLDVALUE;
3686 	pmc_rw_op.pm_value = newvalue;
3687 
3688 	if (PMC_CALL(PMCRW, &pmc_rw_op) < 0)
3689 		return (-1);
3690 
3691 	*oldvaluep = pmc_rw_op.pm_value;
3692 	return (0);
3693 }
3694 
3695 int
3696 pmc_set(pmc_id_t pmc, pmc_value_t value)
3697 {
3698 	struct pmc_op_pmcsetcount sc;
3699 
3700 	sc.pm_pmcid = pmc;
3701 	sc.pm_count = value;
3702 
3703 	if (PMC_CALL(PMCSETCOUNT, &sc) < 0)
3704 		return (-1);
3705 	return (0);
3706 }
3707 
3708 int
3709 pmc_start(pmc_id_t pmc)
3710 {
3711 	struct pmc_op_simple	pmc_start_args;
3712 
3713 	pmc_start_args.pm_pmcid = pmc;
3714 	return (PMC_CALL(PMCSTART, &pmc_start_args));
3715 }
3716 
3717 int
3718 pmc_stop(pmc_id_t pmc)
3719 {
3720 	struct pmc_op_simple	pmc_stop_args;
3721 
3722 	pmc_stop_args.pm_pmcid = pmc;
3723 	return (PMC_CALL(PMCSTOP, &pmc_stop_args));
3724 }
3725 
3726 int
3727 pmc_width(pmc_id_t pmcid, uint32_t *width)
3728 {
3729 	unsigned int i;
3730 	enum pmc_class cl;
3731 
3732 	cl = PMC_ID_TO_CLASS(pmcid);
3733 	for (i = 0; i < cpu_info.pm_nclass; i++)
3734 		if (cpu_info.pm_classes[i].pm_class == cl) {
3735 			*width = cpu_info.pm_classes[i].pm_width;
3736 			return (0);
3737 		}
3738 	errno = EINVAL;
3739 	return (-1);
3740 }
3741 
3742 int
3743 pmc_write(pmc_id_t pmc, pmc_value_t value)
3744 {
3745 	struct pmc_op_pmcrw pmc_write_op;
3746 
3747 	pmc_write_op.pm_pmcid = pmc;
3748 	pmc_write_op.pm_flags = PMC_F_NEWVALUE;
3749 	pmc_write_op.pm_value = value;
3750 	return (PMC_CALL(PMCRW, &pmc_write_op));
3751 }
3752 
3753 int
3754 pmc_writelog(uint32_t userdata)
3755 {
3756 	struct pmc_op_writelog wl;
3757 
3758 	wl.pm_userdata = userdata;
3759 	return (PMC_CALL(WRITELOG, &wl));
3760 }
3761