1 /** 2 * @file ophelp.c 3 * Print out PMC event information 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author John Levon 9 * @author Philippe Elie 10 */ 11 12 #define _GNU_SOURCE 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <limits.h> 17 18 #include "op_version.h" 19 #include "op_events.h" 20 #include "op_popt.h" 21 #include "op_cpufreq.h" 22 #include "op_hw_config.h" 23 #include "op_string.h" 24 #include "op_alloc_counter.h" 25 #include "op_parse_event.h" 26 #include "op_libiberty.h" 27 #include "op_xml_events.h" 28 29 static char const ** chosen_events; 30 static int num_chosen_events; 31 struct parsed_event * parsed_events; 32 static op_cpu cpu_type = CPU_NO_GOOD; 33 static char * cpu_string; 34 static int callgraph_depth; 35 static int want_xml; 36 37 static poptContext optcon; 38 39 40 /// return the Hamming weight (number of set bits) 41 static size_t hweight(size_t mask) 42 { 43 size_t count = 0; 44 45 while (mask) { 46 mask &= mask - 1; 47 count++; 48 } 49 50 return count; 51 } 52 53 static void do_arch_specific_event_help(struct op_event * event) 54 { 55 switch (cpu_type) { 56 case CPU_PPC64_CELL: 57 printf("Group %u :", event->val / 100); 58 break; 59 default: 60 break; 61 } 62 } 63 64 #define LINE_LEN 99 65 66 static void word_wrap(int indent, int *column, char *msg) 67 { 68 while (*msg) { 69 int wlen = strcspn(msg, " "); 70 if (*column + wlen > LINE_LEN) { 71 printf("\n%*s", indent, ""); 72 *column = indent; 73 } 74 printf("%.*s ", wlen, msg); 75 *column += wlen + 1; 76 msg += wlen; 77 msg += strspn(msg, " "); 78 } 79 } 80 81 /** 82 * help_for_event - output event name and description 83 * @param i event number 84 * 85 * output an help string for the event @i 86 */ 87 static void help_for_event(struct op_event * event) 88 { 89 int column; 90 uint i, j; 91 uint mask; 92 size_t nr_counters; 93 char buf[32]; 94 95 do_arch_specific_event_help(event); 96 nr_counters = op_get_nr_counters(cpu_type); 97 98 /* Sanity check */ 99 if (!event) 100 return; 101 102 printf("%s", event->name); 103 104 if(event->counter_mask != 0) { 105 printf(": (counter: "); 106 107 mask = event->counter_mask; 108 if (hweight(mask) == nr_counters) { 109 printf("all"); 110 } else { 111 for (i = 0; i < CHAR_BIT * sizeof(event->counter_mask); ++i) { 112 if (mask & (1 << i)) { 113 printf("%d", i); 114 mask &= ~(1 << i); 115 if (mask) 116 printf(", "); 117 } 118 } 119 } 120 } else if (event->ext != NULL) { 121 /* Handling extended feature interface */ 122 printf(": (ext: %s", event->ext); 123 } else { 124 /* Handling arch_perfmon case */ 125 printf(": (counter: all"); 126 } 127 128 printf(")\n\t"); 129 column = 8; 130 word_wrap(8, &column, event->desc); 131 snprintf(buf, sizeof buf, "(min count: %d)", event->min_count); 132 word_wrap(8, &column, buf); 133 putchar('\n'); 134 135 if (strcmp(event->unit->name, "zero")) { 136 137 printf("\tUnit masks (default 0x%x)\n", 138 event->unit->default_mask); 139 printf("\t----------\n"); 140 141 for (j = 0; j < event->unit->num; j++) { 142 printf("\t0x%.2x: ", 143 event->unit->um[j].value); 144 column = 14; 145 word_wrap(14, &column, event->unit->um[j].desc); 146 putchar('\n'); 147 } 148 } 149 } 150 151 152 static void check_event(struct parsed_event * pev, 153 struct op_event const * event) 154 { 155 int ret; 156 int min_count; 157 int const callgraph_min_count_scale = 15; 158 159 if (!event) { 160 event = find_event_by_name(pev->name, 0, 0); 161 if (event) 162 fprintf(stderr, "Invalid unit mask %x for event %s\n", 163 pev->unit_mask, pev->name); 164 else 165 fprintf(stderr, "No event named %s is available.\n", 166 pev->name); 167 exit(EXIT_FAILURE); 168 } 169 170 ret = op_check_events(0, event->val, pev->unit_mask, cpu_type); 171 172 if (ret & OP_INVALID_UM) { 173 fprintf(stderr, "Invalid unit mask 0x%x for event %s\n", 174 pev->unit_mask, pev->name); 175 exit(EXIT_FAILURE); 176 } 177 178 min_count = event->min_count; 179 if (callgraph_depth) 180 min_count *= callgraph_min_count_scale; 181 if (pev->count < min_count) { 182 fprintf(stderr, "Count %d for event %s is below the " 183 "minimum %d\n", pev->count, pev->name, min_count); 184 exit(EXIT_FAILURE); 185 } 186 } 187 188 189 static void resolve_events(void) 190 { 191 size_t count, count_events; 192 size_t i, j; 193 size_t * counter_map; 194 size_t nr_counters = op_get_nr_counters(cpu_type); 195 struct op_event const * selected_events[num_chosen_events]; 196 197 count = parse_events(parsed_events, num_chosen_events, chosen_events); 198 199 for (i = 0; i < count; ++i) { 200 for (j = i + 1; j < count; ++j) { 201 struct parsed_event * pev1 = &parsed_events[i]; 202 struct parsed_event * pev2 = &parsed_events[j]; 203 204 if (!strcmp(pev1->name, pev2->name) && 205 pev1->count == pev2->count && 206 pev1->unit_mask == pev2->unit_mask && 207 pev1->kernel == pev2->kernel && 208 pev1->user == pev2->user) { 209 fprintf(stderr, "All events must be distinct.\n"); 210 exit(EXIT_FAILURE); 211 } 212 } 213 } 214 215 for (i = 0, count_events = 0; i < count; ++i) { 216 struct parsed_event * pev = &parsed_events[i]; 217 218 /* For 0 unit mask always do wild card match */ 219 selected_events[i] = find_event_by_name(pev->name, pev->unit_mask, 220 pev->unit_mask ? pev->unit_mask_valid : 0); 221 check_event(pev, selected_events[i]); 222 223 if (selected_events[i]->ext == NULL) { 224 count_events++; 225 } 226 } 227 if (count_events > nr_counters) { 228 fprintf(stderr, "Not enough hardware counters. " 229 "Need %lu counters but only has %lu.\n", 230 (unsigned long) count_events, 231 (unsigned long) nr_counters); 232 exit(EXIT_FAILURE); 233 } 234 235 counter_map = map_event_to_counter(selected_events, count, cpu_type); 236 237 if (!counter_map) { 238 fprintf(stderr, "Couldn't allocate hardware counters for the selected events.\n"); 239 exit(EXIT_FAILURE); 240 } 241 242 for (i = 0; i < count; ++i) 243 if(counter_map[i] == (size_t)-1) 244 if (selected_events[i]->ext != NULL) 245 printf("%s ", (char*) selected_events[i]->ext); 246 else 247 printf("N/A "); 248 else 249 printf("%d ", (unsigned int) counter_map[i]); 250 printf("\n"); 251 252 free(counter_map); 253 } 254 255 256 static void show_unit_mask(void) 257 { 258 struct op_event * event; 259 size_t count; 260 261 count = parse_events(parsed_events, num_chosen_events, chosen_events); 262 if (count > 1) { 263 fprintf(stderr, "More than one event specified.\n"); 264 exit(EXIT_FAILURE); 265 } 266 267 event = find_event_by_name(parsed_events[0].name, 0, 0); 268 269 if (!event) { 270 fprintf(stderr, "No such event found.\n"); 271 exit(EXIT_FAILURE); 272 } 273 274 printf("%d\n", event->unit->default_mask); 275 } 276 277 278 static void show_default_event(void) 279 { 280 struct op_default_event_descr descr; 281 282 op_default_event(cpu_type, &descr); 283 284 if (descr.name[0] == '\0') 285 return; 286 287 printf("%s:%lu:%lu:1:1\n", descr.name, descr.count, descr.um); 288 } 289 290 291 static int show_vers; 292 static int get_cpu_type; 293 static int check_events; 294 static int unit_mask; 295 static int get_default_event; 296 297 static struct poptOption options[] = { 298 { "cpu-type", 'c', POPT_ARG_STRING, &cpu_string, 0, 299 "use the given CPU type", "cpu type", }, 300 { "check-events", 'e', POPT_ARG_NONE, &check_events, 0, 301 "check the given event descriptions for validity", NULL, }, 302 { "unit-mask", 'u', POPT_ARG_NONE, &unit_mask, 0, 303 "default unit mask for the given event", NULL, }, 304 { "get-cpu-type", 'r', POPT_ARG_NONE, &get_cpu_type, 0, 305 "show the auto-detected CPU type", NULL, }, 306 { "get-default-event", 'd', POPT_ARG_NONE, &get_default_event, 0, 307 "get the default event", NULL, }, 308 { "callgraph", '\0', POPT_ARG_INT, &callgraph_depth, 0, 309 "use this callgraph depth", "callgraph depth", }, 310 { "version", 'v', POPT_ARG_NONE, &show_vers, 0, 311 "show version", NULL, }, 312 { "xml", 'X', POPT_ARG_NONE, &want_xml, 0, 313 "list events as XML", NULL, }, 314 POPT_AUTOHELP 315 { NULL, 0, 0, NULL, 0, NULL, NULL, }, 316 }; 317 318 /** 319 * get_options - process command line 320 * @param argc program arg count 321 * @param argv program arg array 322 * 323 * Process the arguments, fatally complaining on error. 324 */ 325 static void get_options(int argc, char const * argv[]) 326 { 327 optcon = op_poptGetContext(NULL, argc, argv, options, 0); 328 329 if (show_vers) 330 show_version(argv[0]); 331 332 /* non-option, must be a valid event name or event specs */ 333 chosen_events = poptGetArgs(optcon); 334 335 if(chosen_events) { 336 num_chosen_events = 0; 337 while (chosen_events[num_chosen_events] != NULL) 338 num_chosen_events++; 339 } 340 341 /* don't free the context now, we need chosen_events */ 342 } 343 344 345 /** make valgrind happy */ 346 static void cleanup(void) 347 { 348 int i; 349 if (parsed_events) { 350 for (i = 0; i < num_chosen_events; ++i) { 351 if (parsed_events[i].name) 352 free(parsed_events[i].name); 353 } 354 } 355 op_free_events(); 356 if (optcon) 357 poptFreeContext(optcon); 358 if (parsed_events) 359 free(parsed_events); 360 } 361 362 363 #define MAX_LINE 256 364 int main(int argc, char const * argv[]) 365 { 366 struct list_head * events; 367 struct list_head * pos; 368 char const * pretty; 369 char title[10 * MAX_LINE]; 370 char const * event_doc = ""; 371 372 atexit(cleanup); 373 374 get_options(argc, argv); 375 376 /* usefull for testing purpose to allow to force the cpu type 377 * with --cpu-type */ 378 if (cpu_string) { 379 cpu_type = op_get_cpu_number(cpu_string); 380 } else { 381 cpu_type = op_get_cpu_type(); 382 } 383 384 if (cpu_type == CPU_NO_GOOD) { 385 fprintf(stderr, "cpu_type '%s' is not valid\n", 386 cpu_string ? cpu_string : "unset"); 387 fprintf(stderr, "you should upgrade oprofile or force the " 388 "use of timer mode\n"); 389 exit(EXIT_FAILURE); 390 } 391 392 parsed_events = (struct parsed_event *)xcalloc(num_chosen_events, 393 sizeof(struct parsed_event)); 394 395 pretty = op_get_cpu_type_str(cpu_type); 396 397 if (get_cpu_type) { 398 printf("%s\n", pretty); 399 exit(EXIT_SUCCESS); 400 } 401 402 if (get_default_event) { 403 show_default_event(); 404 exit(EXIT_SUCCESS); 405 } 406 407 if (cpu_type == CPU_TIMER_INT) { 408 if (!check_events) 409 printf("Using timer interrupt.\n"); 410 exit(EXIT_SUCCESS); 411 } 412 413 events = op_events(cpu_type); 414 415 if (!chosen_events && (unit_mask || check_events)) { 416 fprintf(stderr, "No events given.\n"); 417 exit(EXIT_FAILURE); 418 } 419 420 if (unit_mask) { 421 show_unit_mask(); 422 exit(EXIT_SUCCESS); 423 } 424 425 if (check_events) { 426 resolve_events(); 427 exit(EXIT_SUCCESS); 428 } 429 430 /* without --check-events, the only argument must be an event name */ 431 if (chosen_events && chosen_events[0]) { 432 if (chosen_events[1]) { 433 fprintf(stderr, "Too many arguments.\n"); 434 exit(EXIT_FAILURE); 435 } 436 437 list_for_each(pos, events) { 438 struct op_event * event = list_entry(pos, struct op_event, event_next); 439 440 if (strcmp(event->name, chosen_events[0]) == 0) { 441 char const * map = find_mapping_for_event(event->val, cpu_type); 442 if (map) { 443 printf("%d %s\n", event->val, map); 444 } else { 445 printf("%d\n", event->val); 446 } 447 exit(EXIT_SUCCESS); 448 } 449 } 450 fprintf(stderr, "No such event \"%s\"\n", chosen_events[0]); 451 exit(EXIT_FAILURE); 452 } 453 454 /* default: list all events */ 455 456 switch (cpu_type) { 457 case CPU_HAMMER: 458 event_doc = 459 "See BIOS and Kernel Developer's Guide for AMD Athlon and AMD Opteron Processors\n" 460 "(26094.pdf), Section 10.2\n\n"; 461 break; 462 case CPU_FAMILY10: 463 event_doc = 464 "See BIOS and Kernel Developer's Guide for AMD Family 10h Processors\n" 465 "(31116.pdf), Section 3.14\n\n"; 466 break; 467 case CPU_FAMILY11H: 468 event_doc = 469 "See BIOS and Kernel Developer's Guide for AMD Family 11h Processors\n" 470 "(41256.pdf), Section 3.14\n\n"; 471 break; 472 case CPU_FAMILY12H: 473 event_doc = 474 "See BIOS and Kernel Developer's Guide for AMD Family 12h Processors\n"; 475 break; 476 case CPU_FAMILY14H: 477 event_doc = 478 "See BIOS and Kernel Developer's Guide for AMD Family 14h Processors\n"; 479 break; 480 case CPU_FAMILY15H: 481 event_doc = 482 "See BIOS and Kernel Developer's Guide for AMD Family 15h Processors\n"; 483 break; 484 case CPU_ATHLON: 485 event_doc = 486 "See AMD Athlon Processor x86 Code Optimization Guide\n" 487 "(22007.pdf), Appendix D\n\n"; 488 break; 489 case CPU_PPRO: 490 case CPU_PII: 491 case CPU_PIII: 492 case CPU_P6_MOBILE: 493 case CPU_P4: 494 case CPU_P4_HT2: 495 case CPU_CORE: 496 case CPU_CORE_2: 497 case CPU_CORE_I7: 498 case CPU_NEHALEM: 499 case CPU_WESTMERE: 500 case CPU_ATOM: 501 event_doc = 502 "See Intel Architecture Developer's Manual Volume 3B, Appendix A and\n" 503 "Intel Architecture Optimization Reference Manual (730795-001)\n\n"; 504 break; 505 506 case CPU_ARCH_PERFMON: 507 event_doc = 508 "See Intel 64 and IA-32 Architectures Software Developer's Manual\n" 509 "Volume 3B (Document 253669) Chapter 18 for architectural perfmon events\n" 510 "This is a limited set of fallback events because oprofile doesn't know your CPU\n"; 511 break; 512 513 case CPU_IA64: 514 case CPU_IA64_1: 515 case CPU_IA64_2: 516 event_doc = 517 "See Intel Itanium Processor Reference Manual\n" 518 "for Software Development (Document 245320-003),\n" 519 "Intel Itanium Processor Reference Manual\n" 520 "for Software Optimization (Document 245473-003),\n" 521 "Intel Itanium 2 Processor Reference Manual\n" 522 "for Software Development and Optimization (Document 251110-001)\n\n"; 523 break; 524 case CPU_AXP_EV4: 525 case CPU_AXP_EV5: 526 case CPU_AXP_PCA56: 527 case CPU_AXP_EV6: 528 case CPU_AXP_EV67: 529 event_doc = 530 "See Alpha Architecture Reference Manual\n" 531 "http://download.majix.org/dec/alpha_arch_ref.pdf\n"; 532 break; 533 case CPU_ARM_XSCALE1: 534 case CPU_ARM_XSCALE2: 535 event_doc = 536 "See Intel XScale Core Developer's Manual\n" 537 "Chapter 8 Performance Monitoring\n"; 538 break; 539 case CPU_ARM_MPCORE: 540 event_doc = 541 "See ARM11 MPCore Processor Technical Reference Manual r1p0\n" 542 "Page 3-70, performance counters\n"; 543 break; 544 545 case CPU_ARM_V6: 546 event_doc = "See ARM11 Technical Reference Manual\n"; 547 break; 548 549 case CPU_ARM_V7: 550 event_doc = 551 "See Cortex-A8 Technical Reference Manual\n" 552 "Cortex A8 DDI (ARM DDI 0344B, revision r1p1)\n"; 553 break; 554 555 case CPU_ARM_V7_CA9: 556 event_doc = 557 "See Cortex-A9 Technical Reference Manual\n" 558 "Cortex A9 DDI (ARM DDI 0388E, revision r2p0)\n"; 559 break; 560 561 case CPU_PPC64_PA6T: 562 event_doc = 563 "See PA6T Power Implementation Features Book IV\n" 564 "Chapter 7 Performance Counters\n"; 565 break; 566 567 case CPU_PPC64_POWER4: 568 case CPU_PPC64_POWER5: 569 case CPU_PPC64_POWER6: 570 case CPU_PPC64_POWER5p: 571 case CPU_PPC64_POWER5pp: 572 case CPU_PPC64_970: 573 case CPU_PPC64_970MP: 574 case CPU_PPC64_POWER7: 575 case CPU_PPC64_IBM_COMPAT_V1: 576 event_doc = 577 "Obtain PowerPC64 processor documentation at:\n" 578 "http://www-306.ibm.com/chips/techlib/techlib.nsf/productfamilies/PowerPC\n"; 579 break; 580 581 case CPU_PPC64_CELL: 582 event_doc = 583 "Obtain Cell Broadband Engine documentation at:\n" 584 "http://www-306.ibm.com/chips/techlib/techlib.nsf/products/Cell_Broadband_Engine\n"; 585 break; 586 587 case CPU_MIPS_20K: 588 event_doc = 589 "See Programming the MIPS64 20Kc Processor Core User's " 590 "manual available from www.mips.com\n"; 591 break; 592 case CPU_MIPS_24K: 593 event_doc = 594 "See Programming the MIPS32 24K Core " 595 "available from www.mips.com\n"; 596 break; 597 case CPU_MIPS_25K: 598 event_doc = 599 "See Programming the MIPS64 25Kf Processor Core User's " 600 "manual available from www.mips.com\n"; 601 break; 602 case CPU_MIPS_34K: 603 event_doc = 604 "See Programming the MIPS32 34K Core Family " 605 "available from www.mips.com\n"; 606 break; 607 case CPU_MIPS_74K: 608 event_doc = 609 "See Programming the MIPS32 74K Core Family " 610 "available from www.mips.com\n"; 611 break; 612 case CPU_MIPS_1004K: 613 event_doc = 614 "See Programming the MIPS32 1004K Core Family " 615 "available from www.mips.com\n"; 616 break; 617 case CPU_MIPS_5K: 618 event_doc = 619 "See Programming the MIPS64 5K Processor Core Family " 620 "Software User's manual available from www.mips.com\n"; 621 break; 622 case CPU_MIPS_R10000: 623 case CPU_MIPS_R12000: 624 event_doc = 625 "See NEC R10000 / R12000 User's Manual\n" 626 "http://www.necelam.com/docs/files/U10278EJ3V0UM00.pdf\n"; 627 break; 628 case CPU_MIPS_RM7000: 629 event_doc = 630 "See RM7000 Family User Manual " 631 "available from www.pmc-sierra.com\n"; 632 break; 633 case CPU_MIPS_RM9000: 634 event_doc = 635 "See RM9000x2 Family User Manual " 636 "available from www.pmc-sierra.com\n"; 637 break; 638 case CPU_MIPS_SB1: 639 case CPU_MIPS_VR5432: 640 event_doc = 641 "See NEC VR5443 User's Manual, Volume 1\n" 642 "http://www.necelam.com/docs/files/1375_V1.pdf\n"; 643 break; 644 case CPU_MIPS_VR5500: 645 event_doc = 646 "See NEC R10000 / R12000 User's Manual\n" 647 "http://www.necel.com/nesdis/image/U16677EJ3V0UM00.pdf\n"; 648 break; 649 650 case CPU_MIPS_LOONGSON2: 651 event_doc = 652 "See loongson2 RISC Microprocessor Family Reference Manual\n"; 653 break; 654 655 case CPU_PPC_E500: 656 case CPU_PPC_E500_2: 657 event_doc = 658 "See PowerPC e500 Core Complex Reference Manual\n" 659 "Chapter 7: Performance Monitor\n" 660 "Downloadable from http://www.freescale.com\n"; 661 break; 662 663 case CPU_PPC_E300: 664 event_doc = 665 "See PowerPC e300 Core Reference Manual\n" 666 "Downloadable from http://www.freescale.com\n"; 667 break; 668 669 case CPU_PPC_7450: 670 event_doc = 671 "See MPC7450 RISC Microprocessor Family Reference " 672 "Manual\n" 673 "Chapter 11: Performance Monitor\n" 674 "Downloadable from http://www.freescale.com\n"; 675 break; 676 677 case CPU_AVR32: 678 event_doc = 679 "See AVR32 Architecture Manual\n" 680 "Chapter 6: Performance Counters\n" 681 "http://www.atmel.com/dyn/resources/prod_documents/doc32000.pdf\n"; 682 683 case CPU_RTC: 684 break; 685 686 // don't use default, if someone add a cpu he wants a compiler warning 687 // if he forgets to handle it here. 688 case CPU_TIMER_INT: 689 case CPU_NO_GOOD: 690 case MAX_CPU_TYPE: 691 printf("%d is not a valid processor type.\n", cpu_type); 692 exit(EXIT_FAILURE); 693 } 694 695 sprintf(title, "oprofile: available events for CPU type \"%s\"\n\n", pretty); 696 if (want_xml) 697 open_xml_events(title, event_doc, cpu_type); 698 else 699 printf("%s%s", title, event_doc); 700 701 list_for_each(pos, events) { 702 struct op_event * event = list_entry(pos, struct op_event, event_next); 703 if (want_xml) 704 xml_help_for_event(event); 705 else 706 help_for_event(event); 707 } 708 709 if (want_xml) 710 close_xml_events(); 711 712 return EXIT_SUCCESS; 713 } 714