blob: a87a6402760aa824486611a9f14a397fe81e9944 [file] [log] [blame]
Mike Dodd8cfa7022010-11-17 11:12:26 -08001/**
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
29static char const ** chosen_events;
30static int num_chosen_events;
31struct parsed_event * parsed_events;
32static op_cpu cpu_type = CPU_NO_GOOD;
33static char * cpu_string;
34static int callgraph_depth;
35static int want_xml;
36
37static poptContext optcon;
38
39
40/// return the Hamming weight (number of set bits)
41static 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
53static 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
66static 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 */
87static 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
152static 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
189static 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
256static 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
278static 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
291static int show_vers;
292static int get_cpu_type;
293static int check_events;
294static int unit_mask;
295static int get_default_event;
296
297static 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 */
325static 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 */
346static 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
364int 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;
Jeff Brown7a33c862011-02-02 14:00:44 -0800472 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;
Mike Dodd8cfa7022010-11-17 11:12:26 -0800484 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:
Jeff Brown7a33c862011-02-02 14:00:44 -0800498 case CPU_NEHALEM:
499 case CPU_WESTMERE:
Mike Dodd8cfa7022010-11-17 11:12:26 -0800500 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 =
Jeff Brown7a33c862011-02-02 14:00:44 -0800551 "See Cortex-A8 Technical Reference Manual\n"
Mike Dodd8cfa7022010-11-17 11:12:26 -0800552 "Cortex A8 DDI (ARM DDI 0344B, revision r1p1)\n";
553 break;
554
Jeff Brown7a33c862011-02-02 14:00:44 -0800555 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
Mike Dodd8cfa7022010-11-17 11:12:26 -0800561 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;
Jeff Brown7a33c862011-02-02 14:00:44 -0800607 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;
Mike Dodd8cfa7022010-11-17 11:12:26 -0800617 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
Jeff Brown7a33c862011-02-02 14:00:44 -0800650 case CPU_MIPS_LOONGSON2:
651 event_doc =
652 "See loongson2 RISC Microprocessor Family Reference Manual\n";
653 break;
654
Mike Dodd8cfa7022010-11-17 11:12:26 -0800655 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}