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