Home | History | Annotate | Download | only in libop
      1 /**
      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 #include "op_hw_specific.h"
     20 
     21 #include <string.h>
     22 #include <stdlib.h>
     23 #include <stdio.h>
     24 
     25 static LIST_HEAD(events_list);
     26 static LIST_HEAD(um_list);
     27 
     28 static char const * filename;
     29 static unsigned int line_nr;
     30 
     31 static void delete_event(struct op_event * event);
     32 static void read_events(char const * file);
     33 static void read_unit_masks(char const * file);
     34 static void free_unit_mask(struct op_unit_mask * um);
     35 
     36 static char *build_fn(const char *cpu_name, const char *fn)
     37 {
     38 	char *s;
     39 	static const char *dir;
     40 	if (dir == NULL)
     41 		dir = getenv("OPROFILE_EVENTS_DIR");
     42 	if (dir == NULL)
     43 		dir = OP_DATADIR;
     44 	s = xmalloc(strlen(dir) + strlen(cpu_name) + strlen(fn) + 5);
     45 	sprintf(s, "%s/%s/%s", dir, cpu_name, fn);
     46 	return s;
     47 }
     48 
     49 static void parse_error(char const * context)
     50 {
     51 	fprintf(stderr, "oprofile: parse error in %s, line %u\n",
     52 		filename, line_nr);
     53 	fprintf(stderr, "%s\n", context);
     54 	exit(EXIT_FAILURE);
     55 }
     56 
     57 
     58 static int parse_int(char const * str)
     59 {
     60 	int value;
     61 	if (sscanf(str, "%d", &value) != 1)
     62 		parse_error("expected decimal value");
     63 
     64 	return value;
     65 }
     66 
     67 
     68 static int parse_hex(char const * str)
     69 {
     70 	int value;
     71 	/* 0x/0X to force the use of hexa notation for field intended to
     72 	   be in hexadecimal */
     73 	if (sscanf(str, "0x%x", &value) != 1 &&
     74 	    sscanf(str, "0X%x", &value) != 1)
     75 		parse_error("expected hexadecimal value");
     76 
     77 	return value;
     78 }
     79 
     80 
     81 static u64 parse_long_hex(char const * str)
     82 {
     83 	u64 value;
     84 	if (sscanf(str, "%Lx", &value) != 1)
     85 		parse_error("expected long hexadecimal value");
     86 
     87 	fflush(stderr);
     88 	return value;
     89 }
     90 
     91 static void include_um(const char *start, const char *end)
     92 {
     93 	char *s;
     94 	char cpu[end - start + 1];
     95 	int old_line_nr;
     96 	const char *old_filename;
     97 
     98 	strncpy(cpu, start, end - start);
     99 	cpu[end - start] = 0;
    100 	s = build_fn(cpu, "unit_masks");
    101 	old_line_nr = line_nr;
    102 	old_filename = filename;
    103 	read_unit_masks(s);
    104 	line_nr = old_line_nr;
    105 	filename = old_filename;
    106 	free(s);
    107 }
    108 
    109 /* name:MESI type:bitmask default:0x0f */
    110 static void parse_um(struct op_unit_mask * um, char const * line)
    111 {
    112 	int seen_name = 0;
    113 	int seen_type = 0;
    114        	int seen_default = 0;
    115 	char const * valueend = line + 1;
    116        	char const * tagend = line + 1;
    117 	char const * start = line;
    118 
    119 	while (*valueend) {
    120 		valueend = skip_nonws(valueend);
    121 
    122 		while (*tagend != ':' && *tagend)
    123 			++tagend;
    124 
    125 		if (valueend == tagend)
    126 			break;
    127 
    128 		if (!*tagend)
    129 			parse_error("parse_um() expected :value");
    130 
    131 		++tagend;
    132 
    133 		if (strisprefix(start, "include")) {
    134 			if (seen_name + seen_type + seen_default > 0)
    135 				parse_error("include must be on its own");
    136 			free_unit_mask(um);
    137 			include_um(tagend, valueend);
    138 			return;
    139 		}
    140 
    141 		if (strisprefix(start, "name")) {
    142 			if (seen_name)
    143 				parse_error("duplicate name: tag");
    144 			seen_name = 1;
    145 			um->name = op_xstrndup(tagend, valueend - tagend);
    146 		} else if (strisprefix(start, "type")) {
    147 			if (seen_type)
    148 				parse_error("duplicate type: tag");
    149 			seen_type = 1;
    150 			if (strisprefix(tagend, "mandatory")) {
    151 				um->unit_type_mask = utm_mandatory;
    152 			} else if (strisprefix(tagend, "bitmask")) {
    153 				um->unit_type_mask = utm_bitmask;
    154 			} else if (strisprefix(tagend, "exclusive")) {
    155 				um->unit_type_mask = utm_exclusive;
    156 			} else {
    157 				parse_error("invalid unit mask type");
    158 			}
    159 		} else if (strisprefix(start, "default")) {
    160 			if (seen_default)
    161 				parse_error("duplicate default: tag");
    162 			seen_default = 1;
    163 			um->default_mask = parse_hex(tagend);
    164 		} else {
    165 			parse_error("invalid unit mask tag");
    166 		}
    167 
    168 		valueend = skip_ws(valueend);
    169 		tagend = valueend;
    170 		start = valueend;
    171 	}
    172 
    173 	if (!um->name)
    174 		parse_error("Missing name for unit mask");
    175 	if (!seen_type)
    176 		parse_error("Missing type for unit mask");
    177 }
    178 
    179 
    180 /* \t0x08 (M)odified cache state */
    181 static void parse_um_entry(struct op_described_um * entry, char const * line)
    182 {
    183 	char const * c = line;
    184 
    185 	c = skip_ws(c);
    186 	entry->value = parse_hex(c);
    187 	c = skip_nonws(c);
    188 
    189 	if (!*c)
    190 		parse_error("invalid unit mask entry");
    191 
    192 	c = skip_ws(c);
    193 
    194 	if (!*c)
    195 		parse_error("invalid unit mask entry");
    196 
    197 	entry->desc = xstrdup(c);
    198 }
    199 
    200 
    201 static struct op_unit_mask * new_unit_mask(void)
    202 {
    203 	struct op_unit_mask * um = xmalloc(sizeof(struct op_unit_mask));
    204 	memset(um, '\0', sizeof(struct op_unit_mask));
    205 	list_add_tail(&um->um_next, &um_list);
    206 
    207 	return um;
    208 }
    209 
    210 static void free_unit_mask(struct op_unit_mask * um)
    211 {
    212 	list_del(&um->um_next);
    213 	free(um);
    214 }
    215 
    216 /*
    217  * name:zero type:mandatory default:0x0
    218  * \t0x0 No unit mask
    219  */
    220 static void read_unit_masks(char const * file)
    221 {
    222 	struct op_unit_mask * um = NULL;
    223 	char * line;
    224 	FILE * fp = fopen(file, "r");
    225 
    226 	if (!fp) {
    227 		fprintf(stderr,
    228 			"oprofile: could not open unit mask description file %s\n", file);
    229 		exit(EXIT_FAILURE);
    230 	}
    231 
    232 	filename = file;
    233 	line_nr = 1;
    234 
    235 	line = op_get_line(fp);
    236 
    237 	while (line) {
    238 		if (empty_line(line) || comment_line(line))
    239 			goto next;
    240 
    241 		if (line[0] != '\t') {
    242 			um = new_unit_mask();
    243 			parse_um(um, line);
    244 		} else {
    245 			if (!um)
    246 				parse_error("no unit mask name line");
    247 			if (um->num >= MAX_UNIT_MASK)
    248 				parse_error("oprofile: maximum unit mask entries exceeded");
    249 
    250 			parse_um_entry(&um->um[um->num], line);
    251 			++(um->num);
    252 		}
    253 
    254 next:
    255 		free(line);
    256 		line = op_get_line(fp);
    257 		++line_nr;
    258 	}
    259 
    260 	fclose(fp);
    261 }
    262 
    263 
    264 static u32 parse_counter_mask(char const * str)
    265 {
    266 	u32 mask = 0;
    267 	char const * numstart = str;
    268 
    269 	while (*numstart) {
    270 		mask |= 1 << parse_int(numstart);
    271 
    272 		while (*numstart && *numstart != ',')
    273 			++numstart;
    274 		/* skip , unless we reach eos */
    275 		if (*numstart)
    276 			++numstart;
    277 
    278 		numstart = skip_ws(numstart);
    279 	}
    280 
    281 	return mask;
    282 }
    283 
    284 static struct op_unit_mask * try_find_um(char const * value)
    285 {
    286 	struct list_head * pos;
    287 
    288 	list_for_each(pos, &um_list) {
    289 		struct op_unit_mask * um = list_entry(pos, struct op_unit_mask, um_next);
    290 		if (strcmp(value, um->name) == 0) {
    291 			um->used = 1;
    292 			return um;
    293 		}
    294 	}
    295 	return NULL;
    296 }
    297 
    298 static struct op_unit_mask * find_um(char const * value)
    299 {
    300 	struct op_unit_mask * um = try_find_um(value);
    301 	if (um)
    302 		return um;
    303 	fprintf(stderr, "oprofile: could not find unit mask %s\n", value);
    304 	exit(EXIT_FAILURE);
    305 }
    306 
    307 /* um:a,b,c,d merge multiple unit masks */
    308 static struct op_unit_mask * merge_um(char * value)
    309 {
    310 	int num;
    311 	char *s;
    312 	struct op_unit_mask *new, *um;
    313 	enum unit_mask_type type = -1U;
    314 
    315 	um = try_find_um(value);
    316 	if (um)
    317 		return um;
    318 
    319 	new = new_unit_mask();
    320 	new->name = xstrdup(value);
    321 	new->used = 1;
    322 	num = 0;
    323 	while ((s = strsep(&value, ",")) != NULL) {
    324 		unsigned c;
    325 		um = find_um(s);
    326 		if (type == -1U)
    327 			type = um->unit_type_mask;
    328 		if (um->unit_type_mask != type)
    329 			parse_error("combined unit mask must be all the same types");
    330 		if (type != utm_bitmask && type != utm_exclusive)
    331 			parse_error("combined unit mask must be all bitmasks or exclusive");
    332 		new->default_mask |= um->default_mask;
    333 		new->num += um->num;
    334 		if (new->num > MAX_UNIT_MASK)
    335 			parse_error("too many members in combined unit mask");
    336 		for (c = 0; c < um->num; c++, num++) {
    337 			new->um[num] = um->um[c];
    338 			new->um[num].desc = xstrdup(new->um[num].desc);
    339 		}
    340 	}
    341 	if (type == -1U)
    342 		parse_error("Empty unit mask");
    343 	new->unit_type_mask = type;
    344 	return new;
    345 }
    346 
    347 /* parse either a "tag:value" or a ": trailing description string" */
    348 static int next_token(char const ** cp, char ** name, char ** value)
    349 {
    350 	size_t tag_len;
    351 	size_t val_len;
    352 	char const * c = *cp;
    353 	char const * end;
    354 	char const * colon;
    355 
    356 	c = skip_ws(c);
    357 	end = colon = c;
    358 	end = skip_nonws(end);
    359 
    360 	colon = strchr(colon, ':');
    361 
    362 	if (!colon) {
    363 		if (*c)
    364 			parse_error("next_token(): garbage at end of line");
    365 		return 0;
    366 	}
    367 
    368 	if (colon >= end)
    369 		parse_error("next_token() expected ':'");
    370 
    371 	tag_len = colon - c;
    372 	val_len = end - (colon + 1);
    373 
    374 	if (!tag_len) {
    375 		/* : trailing description */
    376 		end = skip_ws(end);
    377 		*name = xstrdup("desc");
    378 		*value = xstrdup(end);
    379 		end += strlen(end);
    380 	} else {
    381 		/* tag:value */
    382 		*name = op_xstrndup(c, tag_len);
    383 		*value = op_xstrndup(colon + 1, val_len);
    384 		end = skip_ws(end);
    385 	}
    386 
    387 	*cp = end;
    388 	return 1;
    389 }
    390 
    391 static void include_events (char *value)
    392 {
    393 	char * event_file;
    394 	const char *old_filename;
    395 	int old_line_nr;
    396 
    397 	event_file = build_fn(value, "events");
    398 	old_line_nr = line_nr;
    399 	old_filename = filename;
    400 	read_events(event_file);
    401 	line_nr = old_line_nr;
    402 	filename = old_filename;
    403 	free(event_file);
    404 }
    405 
    406 static struct op_event * new_event(void)
    407 {
    408 	struct op_event * event = xmalloc(sizeof(struct op_event));
    409 	memset(event, '\0', sizeof(struct op_event));
    410 	list_add_tail(&event->event_next, &events_list);
    411 
    412 	return event;
    413 }
    414 
    415 static void free_event(struct op_event * event)
    416 {
    417 	list_del(&event->event_next);
    418 	free(event);
    419 }
    420 
    421 /* event:0x00 counters:0 um:zero minimum:4096 name:ISSUES : Total issues */
    422 /* event:0x00 ext:xxxxxx um:zero minimum:4096 name:ISSUES : Total issues */
    423 static void read_events(char const * file)
    424 {
    425 	struct op_event * event = NULL;
    426 	char * line;
    427 	char * name;
    428 	char * value;
    429 	char const * c;
    430 	int seen_event, seen_counters, seen_um, seen_minimum, seen_name, seen_ext;
    431 	FILE * fp = fopen(file, "r");
    432 	int tags;
    433 
    434 	if (!fp) {
    435 		fprintf(stderr, "oprofile: could not open event description file %s\n", file);
    436 		exit(EXIT_FAILURE);
    437 	}
    438 
    439 	filename = file;
    440 	line_nr = 1;
    441 
    442 	line = op_get_line(fp);
    443 
    444 	while (line) {
    445 		if (empty_line(line) || comment_line(line))
    446 			goto next;
    447 
    448 		tags = 0;
    449 		seen_name = 0;
    450 		seen_event = 0;
    451 		seen_counters = 0;
    452 		seen_ext = 0;
    453 		seen_um = 0;
    454 		seen_minimum = 0;
    455 		event = new_event();
    456 		event->filter = -1;
    457 		event->ext = NULL;
    458 
    459 		c = line;
    460 		while (next_token(&c, &name, &value)) {
    461 			if (strcmp(name, "name") == 0) {
    462 				if (seen_name)
    463 					parse_error("duplicate name: tag");
    464 				seen_name = 1;
    465 				if (strchr(value, '/') != NULL)
    466 					parse_error("invalid event name");
    467 				if (strchr(value, '.') != NULL)
    468 					parse_error("invalid event name");
    469 				event->name = value;
    470 			} else if (strcmp(name, "event") == 0) {
    471 				if (seen_event)
    472 					parse_error("duplicate event: tag");
    473 				seen_event = 1;
    474 				event->val = parse_hex(value);
    475 				free(value);
    476 			} else if (strcmp(name, "counters") == 0) {
    477 				if (seen_counters)
    478 					parse_error("duplicate counters: tag");
    479 				seen_counters = 1;
    480 				if (!strcmp(value, "cpuid"))
    481 					event->counter_mask = arch_get_counter_mask();
    482 				else
    483 					event->counter_mask = parse_counter_mask(value);
    484 				free(value);
    485 			} else if (strcmp(name, "ext") == 0) {
    486 				if (seen_ext)
    487 					parse_error("duplicate ext: tag");
    488 				seen_ext = 1;
    489 				event->ext = value;
    490 			} else if (strcmp(name, "um") == 0) {
    491 				if (seen_um)
    492 					parse_error("duplicate um: tag");
    493 				seen_um = 1;
    494 				if (strchr(value, ','))
    495 					event->unit = merge_um(value);
    496 				else
    497 					event->unit = find_um(value);
    498 				free(value);
    499 			} else if (strcmp(name, "minimum") == 0) {
    500 				if (seen_minimum)
    501 					parse_error("duplicate minimum: tag");
    502 				seen_minimum = 1;
    503 				event->min_count = parse_int(value);
    504 				free(value);
    505 			} else if (strcmp(name, "desc") == 0) {
    506 				event->desc = value;
    507 			} else if (strcmp(name, "filter") == 0) {
    508 				event->filter = parse_int(value);
    509 				free(value);
    510 			} else if (strcmp(name, "include") == 0) {
    511 				if (tags > 0)
    512 					parse_error("tags before include:");
    513 				free_event(event);
    514 				include_events(value);
    515 				free(value);
    516 				c = skip_ws(c);
    517 				if (*c != '\0' && *c != '#')
    518 					parse_error("non whitespace after include:");
    519 			} else {
    520 				parse_error("unknown tag");
    521 			}
    522 			tags++;
    523 
    524 			free(name);
    525 		}
    526 next:
    527 		free(line);
    528 		line = op_get_line(fp);
    529 		++line_nr;
    530 	}
    531 
    532 	fclose(fp);
    533 }
    534 
    535 
    536 /* usefull for make check */
    537 static int check_unit_mask(struct op_unit_mask const * um,
    538 	char const * cpu_name)
    539 {
    540 	u32 i;
    541 	int err = 0;
    542 
    543 	if (!um->used) {
    544 		fprintf(stderr, "um %s is not used\n", um->name);
    545 		err = EXIT_FAILURE;
    546 	}
    547 
    548 	if (um->unit_type_mask == utm_mandatory && um->num != 1) {
    549 		fprintf(stderr, "mandatory um %s doesn't contain exactly one "
    550 			"entry (%s)\n", um->name, cpu_name);
    551 		err = EXIT_FAILURE;
    552 	} else if (um->unit_type_mask == utm_bitmask) {
    553 		u32 default_mask = um->default_mask;
    554 		for (i = 0; i < um->num; ++i)
    555 			default_mask &= ~um->um[i].value;
    556 
    557 		if (default_mask) {
    558 			fprintf(stderr, "um %s default mask is not valid "
    559 				"(%s)\n", um->name, cpu_name);
    560 			err = EXIT_FAILURE;
    561 		}
    562 	} else {
    563 		for (i = 0; i < um->num; ++i) {
    564 			if (um->default_mask == um->um[i].value)
    565 				break;
    566 		}
    567 
    568 		if (i == um->num) {
    569 			fprintf(stderr, "exclusive um %s default value is not "
    570 				"valid (%s)\n", um->name, cpu_name);
    571 			err = EXIT_FAILURE;
    572 		}
    573 	}
    574 	return err;
    575 }
    576 
    577 static void arch_filter_events(op_cpu cpu_type)
    578 {
    579 	struct list_head * pos, * pos2;
    580 	unsigned filter = arch_get_filter(cpu_type);
    581 	if (!filter)
    582 		return;
    583 	list_for_each_safe (pos, pos2, &events_list) {
    584 		struct op_event * event = list_entry(pos, struct op_event, event_next);
    585 		if (event->filter >= 0 && ((1U << event->filter) & filter))
    586 			delete_event(event);
    587 	}
    588 }
    589 
    590 static void load_events_name(const char *cpu_name)
    591 {
    592 	char * event_file;
    593 	char * um_file;
    594 
    595 	event_file = build_fn(cpu_name, "events");
    596 	um_file = build_fn(cpu_name, "unit_masks");
    597 
    598 	read_unit_masks(um_file);
    599 	read_events(event_file);
    600 
    601 	free(um_file);
    602 	free(event_file);
    603 }
    604 
    605 static void load_events(op_cpu cpu_type)
    606 {
    607 	const char * cpu_name = op_get_cpu_name(cpu_type);
    608 	struct list_head * pos;
    609 	int err = 0;
    610 
    611 	if (!list_empty(&events_list))
    612 		return;
    613 
    614 	load_events_name(cpu_name);
    615 
    616 	arch_filter_events(cpu_type);
    617 
    618 	/* sanity check: all unit mask must be used */
    619 	list_for_each(pos, &um_list) {
    620 		struct op_unit_mask * um = list_entry(pos, struct op_unit_mask, um_next);
    621 		err |= check_unit_mask(um, cpu_name);
    622 	}
    623 	if (err)
    624 		exit(err);
    625 }
    626 
    627 struct list_head * op_events(op_cpu cpu_type)
    628 {
    629 	load_events(cpu_type);
    630 	arch_filter_events(cpu_type);
    631 	return &events_list;
    632 }
    633 
    634 
    635 static void delete_unit_mask(struct op_unit_mask * unit)
    636 {
    637 	u32 cur;
    638 	for (cur = 0 ; cur < unit->num ; ++cur) {
    639 		if (unit->um[cur].desc)
    640 			free(unit->um[cur].desc);
    641 	}
    642 
    643 	if (unit->name)
    644 		free(unit->name);
    645 
    646 	list_del(&unit->um_next);
    647 	free(unit);
    648 }
    649 
    650 
    651 static void delete_event(struct op_event * event)
    652 {
    653 	if (event->name)
    654 		free(event->name);
    655 	if (event->desc)
    656 		free(event->desc);
    657 
    658 	list_del(&event->event_next);
    659 	free(event);
    660 }
    661 
    662 
    663 void op_free_events(void)
    664 {
    665 	struct list_head * pos, * pos2;
    666 	list_for_each_safe(pos, pos2, &events_list) {
    667 		struct op_event * event = list_entry(pos, struct op_event, event_next);
    668 		delete_event(event);
    669 	}
    670 
    671 	list_for_each_safe(pos, pos2, &um_list) {
    672 		struct op_unit_mask * unit = list_entry(pos, struct op_unit_mask, um_next);
    673 		delete_unit_mask(unit);
    674 	}
    675 }
    676 
    677 /* There can be actually multiple events here, so this is not quite correct */
    678 static struct op_event * find_event_any(u32 nr)
    679 {
    680 	struct list_head * pos;
    681 
    682 	list_for_each(pos, &events_list) {
    683 		struct op_event * event = list_entry(pos, struct op_event, event_next);
    684 		if (event->val == nr)
    685 			return event;
    686 	}
    687 
    688 	return NULL;
    689 }
    690 
    691 static struct op_event * find_event_um(u32 nr, u32 um)
    692 {
    693 	struct list_head * pos;
    694 	unsigned int i;
    695 
    696 	list_for_each(pos, &events_list) {
    697 		struct op_event * event = list_entry(pos, struct op_event, event_next);
    698 		if (event->val == nr) {
    699 			for (i = 0; i < event->unit->num; i++) {
    700 				if (event->unit->um[i].value == um)
    701 					return event;
    702 			}
    703 		}
    704 	}
    705 
    706 	return NULL;
    707 }
    708 
    709 static FILE * open_event_mapping_file(char const * cpu_name)
    710 {
    711 	char * ev_map_file;
    712 	char * dir;
    713 	dir = getenv("OPROFILE_EVENTS_DIR");
    714 	if (dir == NULL)
    715 		dir = OP_DATADIR;
    716 
    717 	ev_map_file = xmalloc(strlen(dir) + strlen("/") + strlen(cpu_name) +
    718 	                    strlen("/") + + strlen("event_mappings") + 1);
    719 	strcpy(ev_map_file, dir);
    720 	strcat(ev_map_file, "/");
    721 
    722 	strcat(ev_map_file, cpu_name);
    723 	strcat(ev_map_file, "/");
    724 	strcat(ev_map_file, "event_mappings");
    725 	filename = ev_map_file;
    726 	return (fopen(ev_map_file, "r"));
    727 }
    728 
    729 
    730 /**
    731  *  This function is PPC64-specific.
    732  */
    733 static char const * get_mapping(u32 nr, FILE * fp)
    734 {
    735 	char * line;
    736 	char * name;
    737 	char * value;
    738 	char const * c;
    739 	char * map = NULL;
    740 	int seen_event = 0, seen_mmcr0 = 0, seen_mmcr1 = 0, seen_mmcra = 0;
    741 	u32 mmcr0 = 0;
    742 	u64 mmcr1 = 0;
    743 	u32 mmcra = 0;
    744 	int event_found = 0;
    745 
    746 	line_nr = 1;
    747 	line = op_get_line(fp);
    748 	while (line && !event_found) {
    749 		if (empty_line(line) || comment_line(line))
    750 			goto next;
    751 
    752 		seen_event = 0;
    753 		seen_mmcr0 = 0;
    754 		seen_mmcr1 = 0;
    755 		seen_mmcra = 0;
    756 		mmcr0 = 0;
    757 		mmcr1 = 0;
    758 		mmcra = 0;
    759 
    760 		c = line;
    761 		while (next_token(&c, &name, &value)) {
    762 			if (strcmp(name, "event") == 0) {
    763 				u32 evt;
    764 				if (seen_event)
    765 					parse_error("duplicate event tag");
    766 				seen_event = 1;
    767 				evt = parse_hex(value);
    768 				if (evt == nr)
    769 					event_found = 1;
    770 				free(value);
    771 			} else if (strcmp(name, "mmcr0") == 0) {
    772 				if (seen_mmcr0)
    773 					parse_error("duplicate mmcr0 tag");
    774 				seen_mmcr0 = 1;
    775 				mmcr0 = parse_hex(value);
    776 				free(value);
    777 			} else if (strcmp(name, "mmcr1") == 0) {
    778 				if (seen_mmcr1)
    779 					parse_error("duplicate mmcr1: tag");
    780 				seen_mmcr1 = 1;
    781 				mmcr1 = parse_long_hex(value);
    782 				free(value);
    783 			} else if (strcmp(name, "mmcra") == 0) {
    784 				if (seen_mmcra)
    785 					parse_error("duplicate mmcra: tag");
    786 				seen_mmcra = 1;
    787 				mmcra = parse_hex(value);
    788 				free(value);
    789 			} else {
    790 				parse_error("unknown tag");
    791 			}
    792 
    793 			free(name);
    794 		}
    795 next:
    796 		free(line);
    797 		line = op_get_line(fp);
    798 		++line_nr;
    799 	}
    800 	if (event_found) {
    801 		if (!seen_mmcr0 || !seen_mmcr1 || !seen_mmcra) {
    802 			fprintf(stderr, "Error: Missing information in line %d of event mapping file %s\n", line_nr, filename);
    803 			exit(EXIT_FAILURE);
    804 		}
    805 		map = xmalloc(70);
    806 		snprintf(map, 70, "mmcr0:%u mmcr1:%Lu mmcra:%u",
    807 		         mmcr0, mmcr1, mmcra);
    808 	}
    809 
    810 	return map;
    811 }
    812 
    813 
    814 char const * find_mapping_for_event(u32 nr, op_cpu cpu_type)
    815 {
    816 	char const * cpu_name = op_get_cpu_name(cpu_type);
    817 	FILE * fp = open_event_mapping_file(cpu_name);
    818 	char const * map = NULL;
    819 	switch (cpu_type) {
    820 		case CPU_PPC64_PA6T:
    821 		case CPU_PPC64_970:
    822 		case CPU_PPC64_970MP:
    823 		case CPU_PPC64_POWER4:
    824 		case CPU_PPC64_POWER5:
    825 		case CPU_PPC64_POWER5p:
    826 		case CPU_PPC64_POWER5pp:
    827 		case CPU_PPC64_POWER6:
    828 		case CPU_PPC64_POWER7:
    829 		case CPU_PPC64_IBM_COMPAT_V1:
    830 			if (!fp) {
    831 				fprintf(stderr, "oprofile: could not open event mapping file %s\n", filename);
    832 				exit(EXIT_FAILURE);
    833 			} else {
    834 				map = get_mapping(nr, fp);
    835 			}
    836 			break;
    837 		default:
    838 			break;
    839 	}
    840 
    841 	if (fp)
    842 		fclose(fp);
    843 
    844 	return map;
    845 }
    846 
    847 static int match_event(int i, struct op_event *event, unsigned um)
    848 {
    849 	unsigned v = event->unit->um[i].value;
    850 
    851 	switch (event->unit->unit_type_mask) {
    852 	case utm_exclusive:
    853 	case utm_mandatory:
    854 		return v == um;
    855 
    856 	case utm_bitmask:
    857 		return (v & um) || (!v && v == 0);
    858 	}
    859 
    860 	abort();
    861 }
    862 
    863 struct op_event * find_event_by_name(char const * name, unsigned um, int um_valid)
    864 {
    865 	struct list_head * pos;
    866 
    867 	list_for_each(pos, &events_list) {
    868 		struct op_event * event = list_entry(pos, struct op_event, event_next);
    869 		if (strcmp(event->name, name) == 0) {
    870 			if (um_valid) {
    871 				unsigned i;
    872 
    873 				for (i = 0; i < event->unit->num; i++)
    874 					if (match_event(i, event, um))
    875 						return event;
    876 				continue;
    877 			}
    878 			return event;
    879 		}
    880 	}
    881 
    882 	return NULL;
    883 }
    884 
    885 
    886 struct op_event * op_find_event(op_cpu cpu_type, u32 nr, u32 um)
    887 {
    888 	struct op_event * event;
    889 
    890 	load_events(cpu_type);
    891 
    892 	event = find_event_um(nr, um);
    893 
    894 	return event;
    895 }
    896 
    897 struct op_event * op_find_event_any(op_cpu cpu_type, u32 nr)
    898 {
    899 	load_events(cpu_type);
    900 
    901 	return find_event_any(nr);
    902 }
    903 
    904 int op_check_events(int ctr, u32 nr, u32 um, op_cpu cpu_type)
    905 {
    906 	int ret = OP_INVALID_EVENT;
    907 	size_t i;
    908 	u32 ctr_mask = 1 << ctr;
    909 	struct list_head * pos;
    910 
    911 	load_events(cpu_type);
    912 
    913 	list_for_each(pos, &events_list) {
    914 		struct op_event * event = list_entry(pos, struct op_event, event_next);
    915 		if (event->val != nr)
    916 			continue;
    917 
    918 		ret = OP_OK_EVENT;
    919 
    920 		if ((event->counter_mask & ctr_mask) == 0)
    921 			ret |= OP_INVALID_COUNTER;
    922 
    923 		if (event->unit->unit_type_mask == utm_bitmask) {
    924 			for (i = 0; i < event->unit->num; ++i)
    925 				um &= ~(event->unit->um[i].value);
    926 
    927 			if (um)
    928 				ret |= OP_INVALID_UM;
    929 
    930 		} else {
    931 			for (i = 0; i < event->unit->num; ++i) {
    932 				if (event->unit->um[i].value == um)
    933 					break;
    934 			}
    935 
    936 			if (i == event->unit->num)
    937 				ret |= OP_INVALID_UM;
    938 
    939 		}
    940 
    941 		if (ret == OP_OK_EVENT)
    942 			return ret;
    943 	}
    944 
    945 	return ret;
    946 }
    947 
    948 
    949 void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr)
    950 {
    951 	descr->name = "";
    952 	descr->um = 0x0;
    953 	/* A fixed value of CPU cycles; this should ensure good
    954 	 * granulity even on faster CPUs, though it will generate more
    955 	 * interrupts.
    956 	 */
    957 	descr->count = 100000;
    958 
    959 	switch (cpu_type) {
    960 		case CPU_PPRO:
    961 		case CPU_PII:
    962 		case CPU_PIII:
    963 		case CPU_P6_MOBILE:
    964 		case CPU_CORE:
    965 		case CPU_CORE_2:
    966 		case CPU_ATHLON:
    967 		case CPU_HAMMER:
    968 		case CPU_FAMILY10:
    969 		case CPU_ARCH_PERFMON:
    970 		case CPU_FAMILY11H:
    971  		case CPU_ATOM:
    972  		case CPU_CORE_I7:
    973 		case CPU_NEHALEM:
    974 		case CPU_WESTMERE:
    975 		case CPU_MIPS_LOONGSON2:
    976 		case CPU_FAMILY12H:
    977 		case CPU_FAMILY14H:
    978 		case CPU_FAMILY15H:
    979 			descr->name = "CPU_CLK_UNHALTED";
    980 			break;
    981 
    982 		case CPU_RTC:
    983 			descr->name = "RTC_INTERRUPTS";
    984 			descr->count = 1024;
    985 			break;
    986 
    987 		case CPU_P4:
    988 		case CPU_P4_HT2:
    989 			descr->name = "GLOBAL_POWER_EVENTS";
    990 			descr->um = 0x1;
    991 			break;
    992 
    993 		case CPU_IA64:
    994 		case CPU_IA64_1:
    995 		case CPU_IA64_2:
    996 			descr->count = 1000000;
    997 			descr->name = "CPU_CYCLES";
    998 			break;
    999 
   1000 		case CPU_AXP_EV4:
   1001 		case CPU_AXP_EV5:
   1002 		case CPU_AXP_PCA56:
   1003 		case CPU_AXP_EV6:
   1004 		case CPU_AXP_EV67:
   1005 			descr->name = "CYCLES";
   1006 			break;
   1007 
   1008 		// we could possibly use the CCNT
   1009 		case CPU_ARM_XSCALE1:
   1010 		case CPU_ARM_XSCALE2:
   1011 		case CPU_ARM_MPCORE:
   1012 		case CPU_ARM_V6:
   1013 		case CPU_ARM_V7:
   1014 		case CPU_ARM_V7_CA9:
   1015 		case CPU_AVR32:
   1016 			descr->name = "CPU_CYCLES";
   1017 			break;
   1018 
   1019 		case CPU_PPC64_PA6T:
   1020 		case CPU_PPC64_970:
   1021 		case CPU_PPC64_970MP:
   1022 		case CPU_PPC_7450:
   1023 		case CPU_PPC64_POWER4:
   1024 		case CPU_PPC64_POWER5:
   1025 		case CPU_PPC64_POWER6:
   1026 		case CPU_PPC64_POWER5p:
   1027 		case CPU_PPC64_POWER5pp:
   1028 		case CPU_PPC64_CELL:
   1029 		case CPU_PPC64_POWER7:
   1030 		case CPU_PPC64_IBM_COMPAT_V1:
   1031 			descr->name = "CYCLES";
   1032 			break;
   1033 
   1034 		case CPU_MIPS_20K:
   1035 			descr->name = "CYCLES";
   1036 			break;
   1037 
   1038 		case CPU_MIPS_24K:
   1039 		case CPU_MIPS_34K:
   1040 		case CPU_MIPS_74K:
   1041 		case CPU_MIPS_1004K:
   1042 			descr->name = "INSTRUCTIONS";
   1043 			break;
   1044 
   1045 		case CPU_MIPS_5K:
   1046 		case CPU_MIPS_25K:
   1047 			descr->name = "CYCLES";
   1048 			break;
   1049 
   1050 		case CPU_MIPS_R10000:
   1051 		case CPU_MIPS_R12000:
   1052 			descr->name = "INSTRUCTIONS_GRADUATED";
   1053 			break;
   1054 
   1055 		case CPU_MIPS_RM7000:
   1056 		case CPU_MIPS_RM9000:
   1057 			descr->name = "INSTRUCTIONS_ISSUED";
   1058 			break;
   1059 
   1060 		case CPU_MIPS_SB1:
   1061 			descr->name = "INSN_SURVIVED_STAGE7";
   1062 			break;
   1063 
   1064 		case CPU_MIPS_VR5432:
   1065 		case CPU_MIPS_VR5500:
   1066 			descr->name = "INSTRUCTIONS_EXECUTED";
   1067 			break;
   1068 
   1069 		case CPU_PPC_E500:
   1070 		case CPU_PPC_E500_2:
   1071 		case CPU_PPC_E300:
   1072 			descr->name = "CPU_CLK";
   1073 			break;
   1074 
   1075 		// don't use default, if someone add a cpu he wants a compiler
   1076 		// warning if he forgets to handle it here.
   1077 		case CPU_TIMER_INT:
   1078 		case CPU_NO_GOOD:
   1079 		case MAX_CPU_TYPE:
   1080 			break;
   1081 	}
   1082 }
   1083