blob: b4a10e790634953f88b3342f673b1595d74d5ef4 [file] [log] [blame]
Upstreamcc2ee171970-01-12 13:46:40 +00001/**
2 * @file op_events.c
3 * Details of PMC profiling events
4 *
5 * You can have silliness here.
6 *
7 * @remark Copyright 2002 OProfile authors
8 * @remark Read the file COPYING
9 *
10 * @author John Levon
11 * @author Philippe Elie
12 */
13
14#include "op_events.h"
15#include "op_libiberty.h"
16#include "op_fileio.h"
17#include "op_string.h"
18#include "op_cpufreq.h"
19
20#include <string.h>
21#include <stdlib.h>
22#include <stdio.h>
23
24static LIST_HEAD(events_list);
25static LIST_HEAD(um_list);
26
27static char const * filename;
28static unsigned int line_nr;
29
30static void parse_error(char const * context)
31{
32 fprintf(stderr, "oprofile: parse error in %s, line %u\n",
33 filename, line_nr);
34 fprintf(stderr, "%s\n", context);
35 exit(EXIT_FAILURE);
36}
37
38
39static int parse_int(char const * str)
40{
41 int value;
Ben Cheng2b16b5f2008-10-23 16:07:43 -070042 if (sscanf(str, "%d", &value) != 1)
Upstreamcc2ee171970-01-12 13:46:40 +000043 parse_error("expected decimal value");
Upstreamcc2ee171970-01-12 13:46:40 +000044
45 return value;
46}
47
48
49static int parse_hex(char const * str)
50{
51 int value;
Ben Cheng2b16b5f2008-10-23 16:07:43 -070052 /* 0x/0X to force the use of hexa notation for field intended to
53 be in hexadecimal */
54 if (sscanf(str, "0x%x", &value) != 1 &&
55 sscanf(str, "0X%x", &value) != 1)
Upstreamcc2ee171970-01-12 13:46:40 +000056 parse_error("expected hexadecimal value");
Upstreamcc2ee171970-01-12 13:46:40 +000057
58 return value;
59}
60
61
62static u64 parse_long_hex(char const * str)
63{
64 u64 value;
Ben Cheng2b16b5f2008-10-23 16:07:43 -070065 if (sscanf(str, "%Lx", &value) != 1)
Upstreamcc2ee171970-01-12 13:46:40 +000066 parse_error("expected long hexadecimal value");
Ben Cheng2b16b5f2008-10-23 16:07:43 -070067
Upstreamcc2ee171970-01-12 13:46:40 +000068 fflush(stderr);
69 return value;
70}
71
72
73/* name:MESI type:bitmask default:0x0f */
74static void parse_um(struct op_unit_mask * um, char const * line)
75{
76 int seen_name = 0;
77 int seen_type = 0;
78 int seen_default = 0;
79 char const * valueend = line + 1;
80 char const * tagend = line + 1;
81 char const * start = line;
82
83 while (*valueend) {
84 valueend = skip_nonws(valueend);
85
86 while (*tagend != ':' && *tagend)
87 ++tagend;
88
89 if (valueend == tagend)
90 break;
91
92 if (!*tagend)
93 parse_error("parse_um() expected :value");
94
95 ++tagend;
96
97 if (strisprefix(start, "name")) {
98 if (seen_name)
99 parse_error("duplicate name: tag");
100 seen_name = 1;
101 um->name = op_xstrndup(tagend, valueend - tagend);
102 } else if (strisprefix(start, "type")) {
103 if (seen_type)
104 parse_error("duplicate type: tag");
105 seen_type = 1;
106 if (strisprefix(tagend, "mandatory")) {
107 um->unit_type_mask = utm_mandatory;
108 } else if (strisprefix(tagend, "bitmask")) {
109 um->unit_type_mask = utm_bitmask;
110 } else if (strisprefix(tagend, "exclusive")) {
111 um->unit_type_mask = utm_exclusive;
112 } else {
113 parse_error("invalid unit mask type");
114 }
115 } else if (strisprefix(start, "default")) {
116 if (seen_default)
117 parse_error("duplicate default: tag");
118 seen_default = 1;
119 um->default_mask = parse_hex(tagend);
120 } else {
121 parse_error("invalid unit mask tag");
122 }
123
124 valueend = skip_ws(valueend);
125 tagend = valueend;
126 start = valueend;
127 }
128}
129
130
131/* \t0x08 (M)odified cache state */
132static void parse_um_entry(struct op_described_um * entry, char const * line)
133{
134 char const * c = line;
135
136 c = skip_ws(c);
137 entry->value = parse_hex(c);
138 c = skip_nonws(c);
139
140 if (!*c)
141 parse_error("invalid unit mask entry");
142
143 c = skip_ws(c);
144
145 if (!*c)
146 parse_error("invalid unit mask entry");
147
148 entry->desc = xstrdup(c);
149}
150
151
152static struct op_unit_mask * new_unit_mask(void)
153{
154 struct op_unit_mask * um = xmalloc(sizeof(struct op_unit_mask));
155 memset(um, '\0', sizeof(struct op_unit_mask));
156 list_add_tail(&um->um_next, &um_list);
157
158 return um;
159}
160
161
162/*
163 * name:zero type:mandatory default:0x0
164 * \t0x0 No unit mask
165 */
166static void read_unit_masks(char const * file)
167{
168 struct op_unit_mask * um = NULL;
169 char * line;
170 FILE * fp = fopen(file, "r");
171
172 if (!fp) {
173 fprintf(stderr,
174 "oprofile: could not open unit mask description file %s\n", file);
175 exit(EXIT_FAILURE);
176 }
177
178 filename = file;
179 line_nr = 1;
180
181 line = op_get_line(fp);
182
183 while (line) {
184 if (empty_line(line) || comment_line(line))
185 goto next;
186
187 if (line[0] != '\t') {
188 um = new_unit_mask();
189 parse_um(um, line);
190 } else {
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700191 if (!um)
Upstreamcc2ee171970-01-12 13:46:40 +0000192 parse_error("no unit mask name line");
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700193 if (um->num >= MAX_UNIT_MASK)
Upstreamcc2ee171970-01-12 13:46:40 +0000194 parse_error("oprofile: maximum unit mask entries exceeded");
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700195
Upstreamcc2ee171970-01-12 13:46:40 +0000196 parse_um_entry(&um->um[um->num], line);
197 ++(um->num);
198 }
199
200next:
201 free(line);
202 line = op_get_line(fp);
203 ++line_nr;
204 }
205
206 fclose(fp);
207}
208
209
210static u32 parse_counter_mask(char const * str)
211{
212 u32 mask = 0;
213 char const * numstart = str;
214
215 while (*numstart) {
216 mask |= 1 << parse_int(numstart);
217
218 while (*numstart && *numstart != ',')
219 ++numstart;
220 /* skip , unless we reach eos */
221 if (*numstart)
222 ++numstart;
223
224 numstart = skip_ws(numstart);
225 }
226
227 return mask;
228}
229
230
231static struct op_unit_mask * find_um(char const * value)
232{
233 struct list_head * pos;
234
235 list_for_each(pos, &um_list) {
236 struct op_unit_mask * um = list_entry(pos, struct op_unit_mask, um_next);
237 if (strcmp(value, um->name) == 0)
238 return um;
239 }
240
241 fprintf(stderr, "oprofile: could not find unit mask %s\n", value);
242 exit(EXIT_FAILURE);
243}
244
245
246/* parse either a "tag:value" or a ": trailing description string" */
247static int next_token(char const ** cp, char ** name, char ** value)
248{
249 size_t tag_len;
250 size_t val_len;
251 char const * c = *cp;
252 char const * end;
253 char const * colon;
254
255 c = skip_ws(c);
256 end = colon = c;
257 end = skip_nonws(end);
258
259 colon = strchr(colon, ':');
260
261 if (!colon) {
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700262 if (*c)
Upstreamcc2ee171970-01-12 13:46:40 +0000263 parse_error("next_token(): garbage at end of line");
Upstreamcc2ee171970-01-12 13:46:40 +0000264 return 0;
265 }
266
267 if (colon >= end)
268 parse_error("next_token() expected ':'");
269
270 tag_len = colon - c;
271 val_len = end - (colon + 1);
272
273 if (!tag_len) {
274 /* : trailing description */
275 end = skip_ws(end);
276 *name = xstrdup("desc");
277 *value = xstrdup(end);
278 end += strlen(end);
279 } else {
280 /* tag:value */
281 *name = op_xstrndup(c, tag_len);
282 *value = op_xstrndup(colon + 1, val_len);
283 end = skip_ws(end);
284 }
285
286 *cp = end;
287 return 1;
288}
289
290
291static struct op_event * new_event(void)
292{
293 struct op_event * event = xmalloc(sizeof(struct op_event));
294 memset(event, '\0', sizeof(struct op_event));
295 list_add_tail(&event->event_next, &events_list);
296
297 return event;
298}
299
300
301/* event:0x00 counters:0 um:zero minimum:4096 name:ISSUES : Total issues */
302static void read_events(char const * file)
303{
304 struct op_event * event = NULL;
305 char * line;
306 char * name;
307 char * value;
308 char const * c;
309 int seen_event, seen_counters, seen_um, seen_minimum, seen_name;
310 FILE * fp = fopen(file, "r");
311
312 if (!fp) {
313 fprintf(stderr, "oprofile: could not open event description file %s\n", file);
314 exit(EXIT_FAILURE);
315 }
316
317 filename = file;
318 line_nr = 1;
319
320 line = op_get_line(fp);
321
322 while (line) {
323 if (empty_line(line) || comment_line(line))
324 goto next;
325
326 seen_name = 0;
327 seen_event = 0;
328 seen_counters = 0;
329 seen_um = 0;
330 seen_minimum = 0;
331 event = new_event();
332
333 c = line;
334 while (next_token(&c, &name, &value)) {
335 if (strcmp(name, "name") == 0) {
336 if (seen_name)
337 parse_error("duplicate name: tag");
338 seen_name = 1;
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700339 if (strchr(value, '/') != NULL)
340 parse_error("invalid event name");
341 if (strchr(value, '.') != NULL)
342 parse_error("invalid event name");
Upstreamcc2ee171970-01-12 13:46:40 +0000343 event->name = value;
344 } else if (strcmp(name, "event") == 0) {
345 if (seen_event)
346 parse_error("duplicate event: tag");
347 seen_event = 1;
348 event->val = parse_hex(value);
349 free(value);
350 } else if (strcmp(name, "counters") == 0) {
351 if (seen_counters)
352 parse_error("duplicate counters: tag");
353 seen_counters = 1;
354 event->counter_mask = parse_counter_mask(value);
355 free(value);
356 } else if (strcmp(name, "um") == 0) {
357 if (seen_um)
358 parse_error("duplicate um: tag");
359 seen_um = 1;
360 event->unit = find_um(value);
361 event->unit->used = 1;
362 free(value);
363 } else if (strcmp(name, "minimum") == 0) {
364 if (seen_minimum)
365 parse_error("duplicate minimum: tag");
366 seen_minimum = 1;
367 event->min_count = parse_int(value);
368 free(value);
369 } else if (strcmp(name, "desc") == 0) {
370 event->desc = value;
371 } else {
372 parse_error("unknown tag");
373 }
374
375 free(name);
376 }
377next:
378 free(line);
379 line = op_get_line(fp);
380 ++line_nr;
381 }
382
383 fclose(fp);
384}
385
386
387/* usefull for make check */
388static void check_unit_mask(struct op_unit_mask const * um,
389 char const * cpu_name)
390{
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700391 u32 i;
Upstreamcc2ee171970-01-12 13:46:40 +0000392
393 if (!um->used) {
394 fprintf(stderr, "um %s is not used\n", um->name);
395 exit(EXIT_FAILURE);
396 }
397
398 if (um->unit_type_mask == utm_mandatory && um->num != 1) {
399 fprintf(stderr, "mandatory um %s doesn't contain exactly one "
400 "entry (%s)\n", um->name, cpu_name);
401 exit(EXIT_FAILURE);
402 } else if (um->unit_type_mask == utm_bitmask) {
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700403 u32 default_mask = um->default_mask;
404 for (i = 0; i < um->num; ++i)
Upstreamcc2ee171970-01-12 13:46:40 +0000405 default_mask &= ~um->um[i].value;
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700406
Upstreamcc2ee171970-01-12 13:46:40 +0000407 if (default_mask) {
408 fprintf(stderr, "um %s default mask is not valid "
409 "(%s)\n", um->name, cpu_name);
410 exit(EXIT_FAILURE);
411 }
412 } else {
413 for (i = 0; i < um->num; ++i) {
414 if (um->default_mask == um->um[i].value)
415 break;
416 }
417
418 if (i == um->num) {
419 fprintf(stderr, "exclusive um %s default value is not "
420 "valid (%s)\n", um->name, cpu_name);
421 exit(EXIT_FAILURE);
422 }
423 }
424}
425
426
427static void load_events(op_cpu cpu_type)
428{
429 char const * cpu_name = op_get_cpu_name(cpu_type);
430 char * event_dir;
431 char * event_file;
432 char * um_file;
433 char * dir;
434 struct list_head * pos;
435
436 if (!list_empty(&events_list))
437 return;
438
439 dir = getenv("OPROFILE_EVENTS_DIR");
440 if (dir == NULL)
441 dir = OP_DATADIR;
442
443 event_dir = xmalloc(strlen(dir) + strlen("/") + strlen(cpu_name) +
444 strlen("/") + 1);
445 strcpy(event_dir, dir);
446 strcat(event_dir, "/");
447
448 strcat(event_dir, cpu_name);
449 strcat(event_dir, "/");
450
451 event_file = xmalloc(strlen(event_dir) + strlen("events") + 1);
452 strcpy(event_file, event_dir);
453 strcat(event_file, "events");
454
455 um_file = xmalloc(strlen(event_dir) + strlen("unit_masks") + 1);
456 strcpy(um_file, event_dir);
457 strcat(um_file, "unit_masks");
458
459 read_unit_masks(um_file);
460 read_events(event_file);
461
462 /* sanity check: all unit mask must be used */
463 list_for_each(pos, &um_list) {
464 struct op_unit_mask * um = list_entry(pos, struct op_unit_mask, um_next);
465
466 check_unit_mask(um, cpu_name);
467 }
468
469 free(um_file);
470 free(event_file);
471 free(event_dir);
472}
473
474
475struct list_head * op_events(op_cpu cpu_type)
476{
477 load_events(cpu_type);
478 return &events_list;
479}
480
481
482static void delete_unit_mask(struct op_unit_mask * unit)
483{
484 u32 cur;
485 for (cur = 0 ; cur < unit->num ; ++cur) {
486 if (unit->um[cur].desc)
487 free(unit->um[cur].desc);
488 }
489
490 if (unit->name)
491 free(unit->name);
492
493 list_del(&unit->um_next);
494 free(unit);
495}
496
497
498static void delete_event(struct op_event * event)
499{
500 if (event->name)
501 free(event->name);
502 if (event->desc)
503 free(event->desc);
504
505 list_del(&event->event_next);
506 free(event);
507}
508
509
510void op_free_events(void)
511{
512 struct list_head * pos, * pos2;
513 list_for_each_safe(pos, pos2, &events_list) {
514 struct op_event * event = list_entry(pos, struct op_event, event_next);
515 delete_event(event);
516 }
517
518 list_for_each_safe(pos, pos2, &um_list) {
519 struct op_unit_mask * unit = list_entry(pos, struct op_unit_mask, um_next);
520 delete_unit_mask(unit);
521 }
522}
523
524
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700525static struct op_event * find_event(u32 nr)
Upstreamcc2ee171970-01-12 13:46:40 +0000526{
527 struct list_head * pos;
528
529 list_for_each(pos, &events_list) {
530 struct op_event * event = list_entry(pos, struct op_event, event_next);
531 if (event->val == nr)
532 return event;
533 }
534
535 return NULL;
536}
537
538
539static FILE * open_event_mapping_file(char const * cpu_name)
540{
541 char * ev_map_file;
542 char * dir;
543 dir = getenv("OPROFILE_EVENTS_DIR");
544 if (dir == NULL)
545 dir = OP_DATADIR;
546
547 ev_map_file = xmalloc(strlen(dir) + strlen("/") + strlen(cpu_name) +
548 strlen("/") + + strlen("event_mappings") + 1);
549 strcpy(ev_map_file, dir);
550 strcat(ev_map_file, "/");
551
552 strcat(ev_map_file, cpu_name);
553 strcat(ev_map_file, "/");
554 strcat(ev_map_file, "event_mappings");
555 filename = ev_map_file;
556 return (fopen(ev_map_file, "r"));
557}
558
559
560/**
561 * This function is PPC64-specific.
562 */
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700563static char const * get_mapping(u32 nr, FILE * fp)
Upstreamcc2ee171970-01-12 13:46:40 +0000564{
565 char * line;
566 char * name;
567 char * value;
568 char const * c;
569 char * map = NULL;
570 int seen_event = 0, seen_mmcr0 = 0, seen_mmcr1 = 0, seen_mmcra = 0;
571 u32 mmcr0 = 0;
572 u64 mmcr1 = 0;
573 u32 mmcra = 0;
574 int event_found = 0;
575
576 line_nr = 1;
577 line = op_get_line(fp);
578 while (line && !event_found) {
579 if (empty_line(line) || comment_line(line))
580 goto next;
581
582 seen_event = 0;
583 seen_mmcr0 = 0;
584 seen_mmcr1 = 0;
585 seen_mmcra = 0;
586 mmcr0 = 0;
587 mmcr1 = 0;
588 mmcra = 0;
589
590 c = line;
591 while (next_token(&c, &name, &value)) {
592 if (strcmp(name, "event") == 0) {
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700593 u32 evt;
Upstreamcc2ee171970-01-12 13:46:40 +0000594 if (seen_event)
595 parse_error("duplicate event tag");
596 seen_event = 1;
597 evt = parse_hex(value);
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700598 if (evt == nr)
Upstreamcc2ee171970-01-12 13:46:40 +0000599 event_found = 1;
Upstreamcc2ee171970-01-12 13:46:40 +0000600 free(value);
601 } else if (strcmp(name, "mmcr0") == 0) {
602 if (seen_mmcr0)
603 parse_error("duplicate mmcr0 tag");
604 seen_mmcr0 = 1;
605 mmcr0 = parse_hex(value);
606 free(value);
607 } else if (strcmp(name, "mmcr1") == 0) {
608 if (seen_mmcr1)
609 parse_error("duplicate mmcr1: tag");
610 seen_mmcr1 = 1;
611 mmcr1 = parse_long_hex(value);
612 free(value);
613 } else if (strcmp(name, "mmcra") == 0) {
614 if (seen_mmcra)
615 parse_error("duplicate mmcra: tag");
616 seen_mmcra = 1;
617 mmcra = parse_hex(value);
618 free(value);
619 } else {
620 parse_error("unknown tag");
621 }
622
623 free(name);
624 }
625next:
626 free(line);
627 line = op_get_line(fp);
628 ++line_nr;
629 }
630 if (event_found) {
631 if (!seen_mmcr0 || !seen_mmcr1 || !seen_mmcra) {
632 fprintf(stderr, "Error: Missing information in line %d of event mapping file %s\n", line_nr, filename);
633 exit(EXIT_FAILURE);
634 }
635 map = xmalloc(70);
636 snprintf(map, 70, "mmcr0:%u mmcr1:%Lu mmcra:%u",
637 mmcr0, mmcr1, mmcra);
638 }
639
640 return map;
641}
642
643
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700644char const * find_mapping_for_event(u32 nr, op_cpu cpu_type)
Upstreamcc2ee171970-01-12 13:46:40 +0000645{
646 char const * cpu_name = op_get_cpu_name(cpu_type);
647 FILE * fp = open_event_mapping_file(cpu_name);
648 char const * map = NULL;
649 switch (cpu_type) {
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700650 case CPU_PPC64_PA6T:
Upstreamcc2ee171970-01-12 13:46:40 +0000651 case CPU_PPC64_970:
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700652 case CPU_PPC64_970MP:
Upstreamcc2ee171970-01-12 13:46:40 +0000653 case CPU_PPC64_POWER4:
654 case CPU_PPC64_POWER5:
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700655 case CPU_PPC64_POWER5p:
656 case CPU_PPC64_POWER5pp:
657 case CPU_PPC64_POWER6:
Upstreamcc2ee171970-01-12 13:46:40 +0000658 if (!fp) {
659 fprintf(stderr, "oprofile: could not open event mapping file %s\n", filename);
660 exit(EXIT_FAILURE);
661 } else {
662 map = get_mapping(nr, fp);
663 }
664 break;
665 default:
666 break;
667 }
668
669 if (fp)
670 fclose(fp);
671
672 return map;
673}
674
675
676struct op_event * find_event_by_name(char const * name)
677{
678 struct list_head * pos;
679
680 list_for_each(pos, &events_list) {
681 struct op_event * event = list_entry(pos, struct op_event, event_next);
682 if (strcmp(event->name, name) == 0)
683 return event;
684 }
685
686 return NULL;
687}
688
689
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700690struct op_event * op_find_event(op_cpu cpu_type, u32 nr)
Upstreamcc2ee171970-01-12 13:46:40 +0000691{
692 struct op_event * event;
693
694 load_events(cpu_type);
695
696 event = find_event(nr);
697
698 return event;
699}
700
701
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700702int op_check_events(int ctr, u32 nr, u32 um, op_cpu cpu_type)
Upstreamcc2ee171970-01-12 13:46:40 +0000703{
704 int ret = OP_OK_EVENT;
705 struct op_event * event;
706 size_t i;
707 u32 ctr_mask = 1 << ctr;
708
709 load_events(cpu_type);
710
711 event = find_event(nr);
712
713 if (!event) {
714 ret |= OP_INVALID_EVENT;
715 return ret;
716 }
717
718 if ((event->counter_mask & ctr_mask) == 0)
719 ret |= OP_INVALID_COUNTER;
720
721 if (event->unit->unit_type_mask == utm_bitmask) {
722 for (i = 0; i < event->unit->num; ++i)
723 um &= ~(event->unit->um[i].value);
724
725 if (um)
726 ret |= OP_INVALID_UM;
727
728 } else {
729 for (i = 0; i < event->unit->num; ++i) {
730 if (event->unit->um[i].value == um)
731 break;
732 }
733
734 if (i == event->unit->num)
735 ret |= OP_INVALID_UM;
736 }
737
738 return ret;
739}
740
741
742void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr)
743{
744 descr->name = "";
745 descr->um = 0x0;
746 /* A fixed value of CPU cycles; this should ensure good
747 * granulity even on faster CPUs, though it will generate more
748 * interrupts.
749 */
750 descr->count = 100000;
751
752 switch (cpu_type) {
753 case CPU_PPRO:
754 case CPU_PII:
755 case CPU_PIII:
756 case CPU_P6_MOBILE:
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700757 case CPU_CORE:
758 case CPU_CORE_2:
Upstreamcc2ee171970-01-12 13:46:40 +0000759 case CPU_ATHLON:
760 case CPU_HAMMER:
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700761 case CPU_FAMILY10:
Upstreamcc2ee171970-01-12 13:46:40 +0000762 descr->name = "CPU_CLK_UNHALTED";
763 break;
764
765 case CPU_RTC:
766 descr->name = "RTC_INTERRUPTS";
767 descr->count = 1024;
768 break;
769
770 case CPU_P4:
771 case CPU_P4_HT2:
772 descr->name = "GLOBAL_POWER_EVENTS";
773 descr->um = 0x1;
774 break;
775
776 case CPU_IA64:
777 case CPU_IA64_1:
778 case CPU_IA64_2:
779 descr->count = 1000000;
780 descr->name = "CPU_CYCLES";
781 break;
782
783 case CPU_AXP_EV4:
784 case CPU_AXP_EV5:
785 case CPU_AXP_PCA56:
786 case CPU_AXP_EV6:
787 case CPU_AXP_EV67:
788 descr->name = "CYCLES";
789 break;
790
791 // we could possibly use the CCNT
792 case CPU_ARM_XSCALE1:
793 case CPU_ARM_XSCALE2:
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700794 case CPU_ARM_MPCORE:
795 case CPU_ARM_V6:
796 case CPU_AVR32:
Upstreamcc2ee171970-01-12 13:46:40 +0000797 descr->name = "CPU_CYCLES";
798 break;
799
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700800 case CPU_PPC64_PA6T:
Upstreamcc2ee171970-01-12 13:46:40 +0000801 case CPU_PPC64_970:
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700802 case CPU_PPC64_970MP:
803 case CPU_PPC_7450:
Upstreamcc2ee171970-01-12 13:46:40 +0000804 case CPU_PPC64_POWER4:
805 case CPU_PPC64_POWER5:
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700806 case CPU_PPC64_POWER6:
807 case CPU_PPC64_POWER5p:
808 case CPU_PPC64_POWER5pp:
809 case CPU_PPC64_CELL:
810 descr->name = "CYCLES";
811 break;
812
813 case CPU_MIPS_20K:
Upstreamcc2ee171970-01-12 13:46:40 +0000814 descr->name = "CYCLES";
815 break;
816
817 case CPU_MIPS_24K:
818 descr->name = "INSTRUCTIONS";
819 break;
820
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700821 case CPU_MIPS_34K:
822 descr->name = "INSTRUCTIONS";
823 break;
824
825 case CPU_MIPS_5K:
826 case CPU_MIPS_25K:
827 descr->name = "CYCLES";
828 break;
829
Upstreamcc2ee171970-01-12 13:46:40 +0000830 case CPU_MIPS_R10000:
831 case CPU_MIPS_R12000:
832 descr->name = "INSTRUCTIONS_GRADUATED";
833 break;
834
835 case CPU_MIPS_RM7000:
836 case CPU_MIPS_RM9000:
837 descr->name = "INSTRUCTIONS_ISSUED";
838 break;
839
840 case CPU_MIPS_SB1:
841 descr->name = "INSN_SURVIVED_STAGE7";
842 break;
843
844 case CPU_MIPS_VR5432:
845 case CPU_MIPS_VR5500:
846 descr->name = "INSTRUCTIONS_EXECUTED";
847 break;
848
849 case CPU_PPC_E500:
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700850 case CPU_PPC_E500_2:
851 case CPU_PPC_E300:
Upstreamcc2ee171970-01-12 13:46:40 +0000852 descr->name = "CPU_CLK";
853 break;
Ben Cheng2b16b5f2008-10-23 16:07:43 -0700854
Upstreamcc2ee171970-01-12 13:46:40 +0000855 // don't use default, if someone add a cpu he wants a compiler
856 // warning if he forgets to handle it here.
857 case CPU_TIMER_INT:
858 case CPU_NO_GOOD:
859 case MAX_CPU_TYPE:
860 break;
861 }
862}