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