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