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