~arosales/test/oprofile

« back to all changes in this revision

Viewing changes to utils/ophelp.c

  • Committer: Antonio Rosales
  • Date: 2013-03-28 08:40:26 UTC
  • Revision ID: antonio.rosales@canonical.com-20130328084026-gpqns1mkqd7cnr05
Move files up one directory.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}