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