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