00001
00012 #define _GNU_SOURCE
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <limits.h>
00017
00018 #include "op_version.h"
00019 #include "op_events.h"
00020 #include "op_popt.h"
00021 #include "op_cpufreq.h"
00022 #include "op_hw_config.h"
00023 #include "op_string.h"
00024 #include "op_alloc_counter.h"
00025 #include "op_parse_event.h"
00026 #include "op_libiberty.h"
00027 #include "op_xml_events.h"
00028
00029 static char const ** chosen_events;
00030 static int num_chosen_events;
00031 struct parsed_event * parsed_events;
00032 static op_cpu cpu_type = CPU_NO_GOOD;
00033 static char * cpu_string;
00034 static int callgraph_depth;
00035 static int want_xml;
00036
00037 static poptContext optcon;
00038
00039
00041 static size_t hweight(size_t mask)
00042 {
00043 size_t count = 0;
00044
00045 while (mask) {
00046 mask &= mask - 1;
00047 count++;
00048 }
00049
00050 return count;
00051 }
00052
00053 static void do_arch_specific_event_help(struct op_event * event)
00054 {
00055 switch (cpu_type) {
00056 case CPU_PPC64_CELL:
00057 printf("Group %u :", event->val / 100);
00058 break;
00059 default:
00060 break;
00061 }
00062 }
00063
00064 #define LINE_LEN 99
00065
00066 static void word_wrap(int indent, int *column, char *msg)
00067 {
00068 while (*msg) {
00069 int wlen = strcspn(msg, " ");
00070 if (*column + wlen > LINE_LEN) {
00071 printf("\n%*s", indent, "");
00072 *column = indent;
00073 }
00074 printf("%.*s", wlen, msg);
00075 *column += wlen + 1;
00076 msg += wlen;
00077 msg += strspn(msg, " ");
00078 if (*msg)
00079 putchar(' ');
00080 }
00081 }
00082
00089 static void help_for_event(struct op_event * event)
00090 {
00091 int column;
00092 uint i, j;
00093 uint mask;
00094 size_t nr_counters;
00095 char buf[32];
00096
00097 do_arch_specific_event_help(event);
00098 nr_counters = op_get_nr_counters(cpu_type);
00099
00100
00101 if (!event)
00102 return;
00103
00104 printf("%s", event->name);
00105
00106 if(event->counter_mask != 0) {
00107 printf(": (counter: ");
00108
00109 mask = event->counter_mask;
00110 if (hweight(mask) == nr_counters) {
00111 printf("all");
00112 } else {
00113 for (i = 0; i < CHAR_BIT * sizeof(event->counter_mask); ++i) {
00114 if (mask & (1 << i)) {
00115 printf("%d", i);
00116 mask &= ~(1 << i);
00117 if (mask)
00118 printf(", ");
00119 }
00120 }
00121 }
00122 } else if (event->ext != NULL) {
00123
00124 printf(": (ext: %s", event->ext);
00125 } else {
00126
00127 printf(": (counter: all");
00128 }
00129
00130 printf(")\n\t");
00131 column = 8;
00132 word_wrap(8, &column, event->desc);
00133 snprintf(buf, sizeof buf, " (min count: %d)", event->min_count);
00134 word_wrap(8, &column, buf);
00135 putchar('\n');
00136
00137 if (strcmp(event->unit->name, "zero")) {
00138
00139 printf("\tUnit masks (default 0x%x)\n",
00140 event->unit->default_mask);
00141 printf("\t----------\n");
00142
00143 for (j = 0; j < event->unit->num; j++) {
00144 printf("\t0x%.2x: ",
00145 event->unit->um[j].value);
00146 column = 14;
00147 word_wrap(14, &column, event->unit->um[j].desc);
00148 if (event->unit->um[j].extra) {
00149 u32 extra = event->unit->um[j].extra;
00150
00151 word_wrap(14, &column, " (extra:");
00152 if (extra & EXTRA_EDGE)
00153 word_wrap(14, &column, " edge");
00154 if (extra & EXTRA_INV)
00155 word_wrap(14, &column, " inv");
00156 if ((extra >> EXTRA_CMASK_SHIFT) & EXTRA_CMASK_MASK) {
00157 snprintf(buf, sizeof buf, " cmask=%x",
00158 (extra >> EXTRA_CMASK_SHIFT) & EXTRA_CMASK_MASK);
00159 word_wrap(14, &column, buf);
00160 }
00161 word_wrap(14, &column, ")");
00162 }
00163 putchar('\n');
00164 }
00165 }
00166 }
00167
00168
00169 static void check_event(struct parsed_event * pev,
00170 struct op_event const * event)
00171 {
00172 int ret;
00173 int min_count;
00174 int const callgraph_min_count_scale = 15;
00175
00176 if (!event) {
00177 event = find_event_by_name(pev->name, 0, 0);
00178 if (event)
00179 fprintf(stderr, "Invalid unit mask %x for event %s\n",
00180 pev->unit_mask, pev->name);
00181 else
00182 fprintf(stderr, "No event named %s is available.\n",
00183 pev->name);
00184 exit(EXIT_FAILURE);
00185 }
00186
00187 op_resolve_unit_mask(pev, NULL);
00188
00189 ret = op_check_events(0, event->val, pev->unit_mask, cpu_type);
00190
00191 if (ret & OP_INVALID_UM) {
00192 fprintf(stderr, "Invalid unit mask 0x%x for event %s\n",
00193 pev->unit_mask, pev->name);
00194 exit(EXIT_FAILURE);
00195 }
00196
00197 min_count = event->min_count;
00198 if (callgraph_depth)
00199 min_count *= callgraph_min_count_scale;
00200 if (pev->count < min_count) {
00201 fprintf(stderr, "Count %d for event %s is below the "
00202 "minimum %d\n", pev->count, pev->name, min_count);
00203 exit(EXIT_FAILURE);
00204 }
00205 }
00206
00207
00208 static void resolve_events(void)
00209 {
00210 size_t count, count_events;
00211 size_t i, j;
00212 size_t * counter_map;
00213 size_t nr_counters = op_get_nr_counters(cpu_type);
00214 struct op_event const * selected_events[num_chosen_events];
00215
00216 count = parse_events(parsed_events, num_chosen_events, chosen_events);
00217
00218 for (i = 0; i < count; ++i) {
00219 op_resolve_unit_mask(&parsed_events[i], NULL);
00220 for (j = i + 1; j < count; ++j) {
00221 struct parsed_event * pev1 = &parsed_events[i];
00222 struct parsed_event * pev2 = &parsed_events[j];
00223
00224 if (!strcmp(pev1->name, pev2->name) &&
00225 pev1->count == pev2->count &&
00226 pev1->unit_mask == pev2->unit_mask &&
00227 pev1->kernel == pev2->kernel &&
00228 pev1->user == pev2->user) {
00229 fprintf(stderr, "All events must be distinct.\n");
00230 exit(EXIT_FAILURE);
00231 }
00232 }
00233 }
00234
00235 for (i = 0, count_events = 0; i < count; ++i) {
00236 struct parsed_event * pev = &parsed_events[i];
00237
00238
00239 selected_events[i] = find_event_by_name(pev->name, pev->unit_mask,
00240 pev->unit_mask ? pev->unit_mask_valid : 0);
00241 check_event(pev, selected_events[i]);
00242
00243 if (selected_events[i]->ext == NULL) {
00244 count_events++;
00245 }
00246 }
00247 if (count_events > nr_counters) {
00248 fprintf(stderr, "Not enough hardware counters. "
00249 "Need %lu counters but only has %lu.\n",
00250 (unsigned long) count_events,
00251 (unsigned long) nr_counters);
00252 exit(EXIT_FAILURE);
00253 }
00254
00255 counter_map = map_event_to_counter(selected_events, count, cpu_type);
00256
00257 if (!counter_map) {
00258 fprintf(stderr, "Couldn't allocate hardware counters for the selected events.\n");
00259 exit(EXIT_FAILURE);
00260 }
00261
00262 for (i = 0; i < count; ++i)
00263 if(counter_map[i] == (size_t)-1)
00264 if (selected_events[i]->ext != NULL)
00265 printf("%s ", (char*) selected_events[i]->ext);
00266 else
00267 printf("N/A ");
00268 else
00269 if (strcmp(selected_events[i]->name, TIMER_EVENT_NAME) == 0)
00270 printf("timer ");
00271 else
00272 printf("%d ", (unsigned int) counter_map[i]);
00273 printf("\n");
00274
00275 free(counter_map);
00276 }
00277
00278
00279 static void show_unit_mask(void)
00280 {
00281 size_t count;
00282
00283 count = parse_events(parsed_events, num_chosen_events, chosen_events);
00284 if (count > 1) {
00285 fprintf(stderr, "More than one event specified.\n");
00286 exit(EXIT_FAILURE);
00287 }
00288
00289 op_resolve_unit_mask(parsed_events, NULL);
00290 if (parsed_events[0].unit_mask_name)
00291 printf("%s\n", parsed_events[0].unit_mask_name);
00292 else
00293 printf("%d\n", parsed_events[0].unit_mask);
00294 }
00295
00296 static void show_extra_mask(void)
00297 {
00298 size_t count;
00299 unsigned extra = 0;
00300
00301 count = parse_events(parsed_events, num_chosen_events, chosen_events);
00302 if (count > 1) {
00303 fprintf(stderr, "More than one event specified.\n");
00304 exit(EXIT_FAILURE);
00305 }
00306
00307 op_resolve_unit_mask(parsed_events, &extra);
00308 printf ("%d\n", extra);
00309 }
00310
00311 static void show_default_event(void)
00312 {
00313 struct op_default_event_descr descr;
00314
00315 op_default_event(cpu_type, &descr);
00316
00317 if (descr.name[0] == '\0')
00318 return;
00319
00320 printf("%s:%lu:%lu:1:1\n", descr.name, descr.count, descr.um);
00321 }
00322
00323
00324 static int show_vers;
00325 static int get_cpu_type;
00326 static int check_events;
00327 static int unit_mask;
00328 static int get_default_event;
00329 static int extra_mask;
00330
00331 static struct poptOption options[] = {
00332 { "cpu-type", 'c', POPT_ARG_STRING, &cpu_string, 0,
00333 "use the given CPU type", "cpu type", },
00334 { "check-events", 'e', POPT_ARG_NONE, &check_events, 0,
00335 "check the given event descriptions for validity", NULL, },
00336 { "unit-mask", 'u', POPT_ARG_NONE, &unit_mask, 0,
00337 "default unit mask for the given event", NULL, },
00338 { "get-cpu-type", 'r', POPT_ARG_NONE, &get_cpu_type, 0,
00339 "show the auto-detected CPU type", NULL, },
00340 { "get-default-event", 'd', POPT_ARG_NONE, &get_default_event, 0,
00341 "get the default event", NULL, },
00342 { "callgraph", '\0', POPT_ARG_INT, &callgraph_depth, 0,
00343 "use this callgraph depth", "callgraph depth", },
00344 { "version", 'v', POPT_ARG_NONE, &show_vers, 0,
00345 "show version", NULL, },
00346 { "xml", 'X', POPT_ARG_NONE, &want_xml, 0,
00347 "list events as XML", NULL, },
00348 { "extra-mask", 'E', POPT_ARG_NONE, &extra_mask, 0,
00349 "print extra mask for event", NULL, },
00350 POPT_AUTOHELP
00351 { NULL, 0, 0, NULL, 0, NULL, NULL, },
00352 };
00353
00361 static void get_options(int argc, char const * argv[])
00362 {
00363 optcon = op_poptGetContext(NULL, argc, argv, options, 0);
00364
00365 if (show_vers)
00366 show_version(argv[0]);
00367
00368
00369 chosen_events = poptGetArgs(optcon);
00370
00371 if(chosen_events) {
00372 num_chosen_events = 0;
00373 while (chosen_events[num_chosen_events] != NULL)
00374 num_chosen_events++;
00375 }
00376
00377
00378 }
00379
00380
00382 static void cleanup(void)
00383 {
00384 int i;
00385 if (parsed_events) {
00386 for (i = 0; i < num_chosen_events; ++i) {
00387 if (parsed_events[i].name)
00388 free(parsed_events[i].name);
00389 }
00390 }
00391 op_free_events();
00392 if (optcon)
00393 poptFreeContext(optcon);
00394 if (parsed_events)
00395 free(parsed_events);
00396 }
00397
00398
00399 #define MAX_LINE 256
00400 int main(int argc, char const * argv[])
00401 {
00402 struct list_head * events;
00403 struct list_head * pos;
00404 char const * pretty;
00405 char title[10 * MAX_LINE];
00406 char const * event_doc = "";
00407
00408 atexit(cleanup);
00409
00410 get_options(argc, argv);
00411
00412
00413
00414 if (cpu_string) {
00415 cpu_type = op_get_cpu_number(cpu_string);
00416 } else {
00417 cpu_type = op_get_cpu_type();
00418 }
00419
00420 if (cpu_type == CPU_NO_GOOD) {
00421 fprintf(stderr, "cpu_type '%s' is not valid\n",
00422 cpu_string ? cpu_string : "unset");
00423 fprintf(stderr, "you should upgrade oprofile or force the "
00424 "use of timer mode\n");
00425 exit(EXIT_FAILURE);
00426 }
00427
00428 parsed_events = (struct parsed_event *)xcalloc(num_chosen_events,
00429 sizeof(struct parsed_event));
00430
00431 pretty = op_get_cpu_type_str(cpu_type);
00432
00433 if (get_cpu_type) {
00434 printf("%s\n", pretty);
00435 exit(EXIT_SUCCESS);
00436 }
00437
00438 if (get_default_event) {
00439 show_default_event();
00440 exit(EXIT_SUCCESS);
00441 }
00442
00443 if (cpu_type == CPU_TIMER_INT) {
00444 if (!check_events)
00445 printf("Using timer interrupt.\n");
00446 exit(EXIT_SUCCESS);
00447 }
00448
00449 events = op_events(cpu_type);
00450
00451 if (!chosen_events && (unit_mask || check_events || extra_mask)) {
00452 fprintf(stderr, "No events given.\n");
00453 exit(EXIT_FAILURE);
00454 }
00455
00456 if (unit_mask) {
00457 show_unit_mask();
00458 exit(EXIT_SUCCESS);
00459 }
00460
00461 if (extra_mask) {
00462 show_extra_mask();
00463 exit(EXIT_SUCCESS);
00464 }
00465
00466 if (check_events) {
00467 resolve_events();
00468 exit(EXIT_SUCCESS);
00469 }
00470
00471
00472 if (chosen_events && chosen_events[0]) {
00473 if (chosen_events[1]) {
00474 fprintf(stderr, "Too many arguments.\n");
00475 exit(EXIT_FAILURE);
00476 }
00477
00478 list_for_each(pos, events) {
00479 struct op_event * event = list_entry(pos, struct op_event, event_next);
00480
00481 if (strcmp(event->name, chosen_events[0]) == 0) {
00482 char const * map = find_mapping_for_event(event->val, cpu_type);
00483 if (map) {
00484 printf("%d %s\n", event->val, map);
00485 } else {
00486 printf("%d\n", event->val);
00487 }
00488 exit(EXIT_SUCCESS);
00489 }
00490 }
00491 fprintf(stderr, "No such event \"%s\"\n", chosen_events[0]);
00492 exit(EXIT_FAILURE);
00493 }
00494
00495
00496
00497 switch (cpu_type) {
00498 case CPU_HAMMER:
00499 event_doc =
00500 "See BIOS and Kernel Developer's Guide for AMD Athlon and AMD Opteron Processors\n"
00501 "(26094.pdf), Section 10.2\n\n";
00502 break;
00503 case CPU_FAMILY10:
00504 event_doc =
00505 "See BIOS and Kernel Developer's Guide for AMD Family 10h Processors\n"
00506 "(31116.pdf), Section 3.14\n\n";
00507 break;
00508 case CPU_FAMILY11H:
00509 event_doc =
00510 "See BIOS and Kernel Developer's Guide for AMD Family 11h Processors\n"
00511 "(41256.pdf), Section 3.14\n\n";
00512 break;
00513 case CPU_FAMILY12H:
00514 event_doc =
00515 "See BIOS and Kernel Developer's Guide for AMD Family 12h Processors\n";
00516 break;
00517 case CPU_FAMILY14H:
00518 event_doc =
00519 "See BIOS and Kernel Developer's Guide for AMD Family 14h Processors\n";
00520 break;
00521 case CPU_FAMILY15H:
00522 event_doc =
00523 "See BIOS and Kernel Developer's Guide for AMD Family 15h Processors\n";
00524 break;
00525 case CPU_ATHLON:
00526 event_doc =
00527 "See AMD Athlon Processor x86 Code Optimization Guide\n"
00528 "(22007.pdf), Appendix D\n\n";
00529 break;
00530 case CPU_PPRO:
00531 case CPU_PII:
00532 case CPU_PIII:
00533 case CPU_P6_MOBILE:
00534 case CPU_P4:
00535 case CPU_P4_HT2:
00536 case CPU_CORE:
00537 case CPU_CORE_2:
00538 case CPU_CORE_I7:
00539 case CPU_NEHALEM:
00540 case CPU_WESTMERE:
00541 case CPU_SANDYBRIDGE:
00542 case CPU_IVYBRIDGE:
00543 case CPU_ATOM:
00544 event_doc =
00545 "See Intel Architecture Developer's Manual Volume 3B, Appendix A and\n"
00546 "Intel Architecture Optimization Reference Manual (730795-001)\n\n";
00547 break;
00548
00549 case CPU_ARCH_PERFMON:
00550 event_doc =
00551 "See Intel 64 and IA-32 Architectures Software Developer's Manual\n"
00552 "Volume 3B (Document 253669) Chapter 18 for architectural perfmon events\n"
00553 "This is a limited set of fallback events because oprofile doesn't know your CPU\n";
00554 break;
00555
00556 case CPU_IA64:
00557 case CPU_IA64_1:
00558 case CPU_IA64_2:
00559 event_doc =
00560 "See Intel Itanium Processor Reference Manual\n"
00561 "for Software Development (Document 245320-003),\n"
00562 "Intel Itanium Processor Reference Manual\n"
00563 "for Software Optimization (Document 245473-003),\n"
00564 "Intel Itanium 2 Processor Reference Manual\n"
00565 "for Software Development and Optimization (Document 251110-001)\n\n";
00566 break;
00567 case CPU_AXP_EV4:
00568 case CPU_AXP_EV5:
00569 case CPU_AXP_PCA56:
00570 case CPU_AXP_EV6:
00571 case CPU_AXP_EV67:
00572 event_doc =
00573 "See Alpha Architecture Reference Manual\n"
00574 "http://download.majix.org/dec/alpha_arch_ref.pdf\n";
00575 break;
00576 case CPU_ARM_XSCALE1:
00577 case CPU_ARM_XSCALE2:
00578 event_doc =
00579 "See Intel XScale Core Developer's Manual\n"
00580 "Chapter 8 Performance Monitoring\n";
00581 break;
00582 case CPU_ARM_MPCORE:
00583 event_doc =
00584 "See ARM11 MPCore Processor Technical Reference Manual r1p0\n"
00585 "Page 3-70, performance counters\n";
00586 break;
00587
00588 case CPU_ARM_V6:
00589 event_doc = "See ARM11 Technical Reference Manual\n";
00590 break;
00591
00592 case CPU_ARM_V7:
00593 event_doc =
00594 "See Cortex-A8 Technical Reference Manual\n"
00595 "Cortex A8 DDI (ARM DDI 0344B, revision r1p1)\n";
00596 break;
00597
00598 case CPU_ARM_SCORPION:
00599 event_doc =
00600 "See ARM Architecture Reference Manual ARMv7-A and ARMv7-R Edition\n"
00601 "Scorpion Processor Family Programmer's Reference Manual (PRM)\n";
00602 break;
00603
00604 case CPU_ARM_SCORPIONMP:
00605 event_doc =
00606 "See ARM Architecture Reference Manual ARMv7-A and ARMv7-R Edition\n"
00607 "Scorpion Processor Family Programmer's Reference Manual (PRM)\n";
00608 break;
00609
00610 case CPU_ARM_V7_CA9:
00611 event_doc =
00612 "See Cortex-A9 Technical Reference Manual\n"
00613 "Cortex A9 DDI (ARM DDI 0388E, revision r2p0)\n";
00614 break;
00615
00616 case CPU_ARM_V7_CA5:
00617 event_doc =
00618 "See Cortex-A5 Technical Reference Manual\n"
00619 "Cortex A5 DDI (ARM DDI 0433B, revision r0p1)\n";
00620 break;
00621
00622 case CPU_ARM_V7_CA7:
00623 event_doc =
00624 "See Cortex-A7 MPCore Technical Reference Manual\n"
00625 "Cortex A7 DDI (ARM DDI 0464D, revision r0p3)\n";
00626 break;
00627
00628 case CPU_ARM_V7_CA15:
00629 event_doc =
00630 "See Cortex-A15 MPCore Technical Reference Manual\n"
00631 "Cortex A15 DDI (ARM DDI 0438F, revision r3p1)\n";
00632 break;
00633
00634 case CPU_PPC64_PA6T:
00635 event_doc =
00636 "See PA6T Power Implementation Features Book IV\n"
00637 "Chapter 7 Performance Counters\n";
00638 break;
00639
00640 case CPU_PPC64_POWER4:
00641 case CPU_PPC64_POWER5:
00642 case CPU_PPC64_POWER6:
00643 case CPU_PPC64_POWER5p:
00644 case CPU_PPC64_POWER5pp:
00645 case CPU_PPC64_970:
00646 case CPU_PPC64_970MP:
00647 case CPU_PPC64_POWER7:
00648 case CPU_PPC64_IBM_COMPAT_V1:
00649 event_doc =
00650 "Obtain PowerPC64 processor documentation at:\n"
00651 "http://www-306.ibm.com/chips/techlib/techlib.nsf/productfamilies/PowerPC\n";
00652 break;
00653
00654 case CPU_PPC64_CELL:
00655 event_doc =
00656 "Obtain Cell Broadband Engine documentation at:\n"
00657 "http://www-306.ibm.com/chips/techlib/techlib.nsf/products/Cell_Broadband_Engine\n";
00658 break;
00659
00660 case CPU_MIPS_20K:
00661 event_doc =
00662 "See Programming the MIPS64 20Kc Processor Core User's "
00663 "manual available from www.mips.com\n";
00664 break;
00665 case CPU_MIPS_24K:
00666 event_doc =
00667 "See Programming the MIPS32 24K Core "
00668 "available from www.mips.com\n";
00669 break;
00670 case CPU_MIPS_25K:
00671 event_doc =
00672 "See Programming the MIPS64 25Kf Processor Core User's "
00673 "manual available from www.mips.com\n";
00674 break;
00675 case CPU_MIPS_34K:
00676 event_doc =
00677 "See Programming the MIPS32 34K Core Family "
00678 "available from www.mips.com\n";
00679 break;
00680 case CPU_MIPS_74K:
00681 event_doc =
00682 "See Programming the MIPS32 74K Core Family "
00683 "available from www.mips.com\n";
00684 break;
00685 case CPU_MIPS_1004K:
00686 event_doc =
00687 "See Programming the MIPS32 1004K Core Family "
00688 "available from www.mips.com\n";
00689 break;
00690 case CPU_MIPS_5K:
00691 event_doc =
00692 "See Programming the MIPS64 5K Processor Core Family "
00693 "Software User's manual available from www.mips.com\n";
00694 break;
00695 case CPU_MIPS_R10000:
00696 case CPU_MIPS_R12000:
00697 event_doc =
00698 "See NEC R10000 / R12000 User's Manual\n"
00699 "http://www.necelam.com/docs/files/U10278EJ3V0UM00.pdf\n";
00700 break;
00701 case CPU_MIPS_RM7000:
00702 event_doc =
00703 "See RM7000 Family User Manual "
00704 "available from www.pmc-sierra.com\n";
00705 break;
00706 case CPU_MIPS_RM9000:
00707 event_doc =
00708 "See RM9000x2 Family User Manual "
00709 "available from www.pmc-sierra.com\n";
00710 break;
00711 case CPU_MIPS_SB1:
00712 case CPU_MIPS_VR5432:
00713 event_doc =
00714 "See NEC VR5443 User's Manual, Volume 1\n"
00715 "http://www.necelam.com/docs/files/1375_V1.pdf\n";
00716 break;
00717 case CPU_MIPS_VR5500:
00718 event_doc =
00719 "See NEC R10000 / R12000 User's Manual\n"
00720 "http://www.necel.com/nesdis/image/U16677EJ3V0UM00.pdf\n";
00721 break;
00722
00723 case CPU_MIPS_LOONGSON2:
00724 event_doc =
00725 "See loongson2 RISC Microprocessor Family Reference Manual\n";
00726 break;
00727
00728 case CPU_PPC_E500:
00729 case CPU_PPC_E500_2:
00730 event_doc =
00731 "See PowerPC e500 Core Complex Reference Manual\n"
00732 "Chapter 7: Performance Monitor\n"
00733 "Downloadable from http://www.freescale.com\n";
00734 break;
00735
00736 case CPU_PPC_E300:
00737 event_doc =
00738 "See PowerPC e300 Core Reference Manual\n"
00739 "Downloadable from http://www.freescale.com\n";
00740 break;
00741
00742 case CPU_PPC_7450:
00743 event_doc =
00744 "See MPC7450 RISC Microprocessor Family Reference "
00745 "Manual\n"
00746 "Chapter 11: Performance Monitor\n"
00747 "Downloadable from http://www.freescale.com\n";
00748 break;
00749
00750 case CPU_AVR32:
00751 event_doc =
00752 "See AVR32 Architecture Manual\n"
00753 "Chapter 6: Performance Counters\n"
00754 "http://www.atmel.com/dyn/resources/prod_documents/doc32000.pdf\n";
00755
00756 break;
00757
00758 case CPU_TILE_TILE64:
00759 case CPU_TILE_TILEPRO:
00760 case CPU_TILE_TILEGX:
00761 event_doc =
00762 "See Tilera development doc: Multicore Development "
00763 "Environment Optimization Guide.\n"
00764 "Contact Tilera Corporation or visit "
00765 "http://www.tilera.com for more information.\n";
00766 break;
00767
00768 case CPU_S390_Z10:
00769 case CPU_S390_Z196:
00770 event_doc = "IBM System z CPU Measurement Facility\n"
00771 "http://www-01.ibm.com/support/docview.wss"
00772 "?uid=isg26fcd1cc32246f4c8852574ce0044734a\n";
00773 break;
00774
00775 case CPU_RTC:
00776 break;
00777
00778
00779
00780 case CPU_TIMER_INT:
00781 case CPU_NO_GOOD:
00782 case MAX_CPU_TYPE:
00783 printf("%d is not a valid processor type.\n", cpu_type);
00784 exit(EXIT_FAILURE);
00785 }
00786
00787 sprintf(title, "oprofile: available events for CPU type \"%s\"\n\n", pretty);
00788 if (want_xml)
00789 open_xml_events(title, event_doc, cpu_type);
00790 else {
00791 printf("%s%s", title, event_doc);
00792 printf("For architectures using unit masks, you may be able to specify\n"
00793 "unit masks by name. See 'opcontrol' or 'operf' man page for more details.\n\n");
00794 }
00795
00796 list_for_each(pos, events) {
00797 struct op_event * event = list_entry(pos, struct op_event, event_next);
00798 if (want_xml)
00799 xml_help_for_event(event);
00800 else
00801 help_for_event(event);
00802 }
00803
00804 if (want_xml)
00805 close_xml_events();
00806
00807 return EXIT_SUCCESS;
00808 }