/**
 * @file op_events.c
 * Details of PMC profiling events
 *
 * You can have silliness here.
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author John Levon
 * @author Philippe Elie
 */

#include "op_events.h"
#include "op_libiberty.h"
#include "op_fileio.h"
#include "op_string.h"
#include "op_cpufreq.h"
#include "op_hw_specific.h"
#include "op_parse_event.h"

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

static LIST_HEAD(events_list);
static LIST_HEAD(um_list);

static char const * filename;
static unsigned int line_nr;

static void delete_event(struct op_event * event);
static void read_events(char const * file);
static void read_unit_masks(char const * file);
static void free_unit_mask(struct op_unit_mask * um);

static char *build_fn(const char *cpu_name, const char *fn)
{
	char *s;
	static const char *dir;
	if (dir == NULL)
		dir = getenv("OPROFILE_EVENTS_DIR");
	if (dir == NULL)
		dir = OP_DATADIR;
	s = xmalloc(strlen(dir) + strlen(cpu_name) + strlen(fn) + 5);
	sprintf(s, "%s/%s/%s", dir, cpu_name, fn);
	return s;
}

static void parse_error(char const * context)
{
	fprintf(stderr, "oprofile: parse error in %s, line %u\n",
		filename, line_nr);
	fprintf(stderr, "%s\n", context);
	exit(EXIT_FAILURE);
}


static int parse_int(char const * str)
{
	int value;
	if (sscanf(str, "%d", &value) != 1)
		parse_error("expected decimal value");

	return value;
}


static int parse_hex(char const * str)
{
	int value;
	/* 0x/0X to force the use of hexa notation for field intended to
	   be in hexadecimal */
	if (sscanf(str, "0x%x", &value) != 1 &&
	    sscanf(str, "0X%x", &value) != 1)
		parse_error("expected hexadecimal value");

	return value;
}


static u64 parse_long_hex(char const * str)
{
	u64 value;
	if (sscanf(str, "%Lx", &value) != 1)
		parse_error("expected long hexadecimal value");

	fflush(stderr);
	return value;
}

static void include_um(const char *start, const char *end)
{
	char *s;
	char cpu[end - start + 1];
	int old_line_nr;
	const char *old_filename;

	strncpy(cpu, start, end - start);
	cpu[end - start] = 0;
	s = build_fn(cpu, "unit_masks");
	old_line_nr = line_nr;
	old_filename = filename;
	read_unit_masks(s);
	line_nr = old_line_nr;
	filename = old_filename;
	free(s);
}

/* extra:cmask=12,inv,edge */
unsigned parse_extra(const char *s)
{
	unsigned v, w;
	int o;

	/* This signifies that the first word of the description is unique */
	v = EXTRA_NONE;
	while (*s) {
		if (isspace(*s))
			break;
		if (strisprefix(s, "edge")) {
			v |= EXTRA_EDGE;
			s += 4;
		} else if (strisprefix(s, "inv")) {
			v |= EXTRA_INV;
			s += 3;
		} else if (sscanf(s, "cmask=%x%n", &w, &o) >= 1) {
			v |= (w & EXTRA_CMASK_MASK) << EXTRA_CMASK_SHIFT;
			s += o;
		} else if (strisprefix(s, "any")) {
			v |= EXTRA_ANY;
			s += 3;
		} else if (strisprefix(s, "pebs")) {
			v |= EXTRA_PEBS;
			s += 4;
		} else {
			parse_error("Illegal extra field modifier");
		}
		if (*s == ',')
			++s;
	}
	return v;
}

/* name:MESI type:bitmask default:0x0f */
static void parse_um(struct op_unit_mask * um, char const * line)
{
	int seen_name = 0;
	int seen_type = 0;
       	int seen_default = 0;
	char const * valueend = line + 1;
       	char const * tagend = line + 1;
	char const * start = line;

	while (*valueend) {
		valueend = skip_nonws(valueend);

		while (*tagend != ':' && *tagend)
			++tagend;

		if (valueend == tagend)
			break;

		if (!*tagend)
			parse_error("parse_um() expected :value");

		++tagend;

		if (strisprefix(start, "include")) {
			if (seen_name + seen_type + seen_default > 0)
				parse_error("include must be on its own");
			free_unit_mask(um);
			include_um(tagend, valueend);
			return;
		}

		if (strisprefix(start, "name")) {
			if (seen_name)
				parse_error("duplicate name: tag");
			seen_name = 1;
			um->name = op_xstrndup(tagend, valueend - tagend);
		} else if (strisprefix(start, "type")) {
			if (seen_type)
				parse_error("duplicate type: tag");
			seen_type = 1;
			if (strisprefix(tagend, "mandatory")) {
				um->unit_type_mask = utm_mandatory;
			} else if (strisprefix(tagend, "bitmask")) {
				um->unit_type_mask = utm_bitmask;
			} else if (strisprefix(tagend, "exclusive")) {
				um->unit_type_mask = utm_exclusive;
			} else {
				parse_error("invalid unit mask type");
			}
		} else if (strisprefix(start, "default")) {
			if (seen_default)
				parse_error("duplicate default: tag");
			seen_default = 1;
			if (0 != strncmp(tagend, "0x", 2)) {
				um->default_mask_name = op_xstrndup(
					tagend, valueend - tagend);
			} else {
				um->default_mask = parse_hex(tagend);
			}
		} else {
			parse_error("invalid unit mask tag");
		}

		valueend = skip_ws(valueend);
		tagend = valueend;
		start = valueend;
	}

	if (!um->name)
		parse_error("Missing name for unit mask");
	if (!seen_type)
		parse_error("Missing type for unit mask");
}


/* \t0x08 (M)odified cache state */
/* \t0x08 extra:inv,cmask=... mod_cach_state (M)odified cache state */
static void parse_um_entry(struct op_described_um * entry, char const * line)
{
	char const * c = line;

	/* value */
	c = skip_ws(c);
	entry->value = parse_hex(c);

	/* extra: */
	c = skip_nonws(c);
	c = skip_ws(c);
	if (!*c)
		goto invalid_out;

	if (strisprefix(c, "extra:")) {
		c += 6;
		entry->extra = parse_extra(c);
		/* named mask */
		c = skip_nonws(c);
		c = skip_ws(c);
		if (!*c)
			goto invalid_out;

		/* "extra:" !!ALWAYS!! followed by named mask */
		entry->name = op_xstrndup(c, strcspn(c, " \t"));
		c = skip_nonws(c);
		c = skip_ws(c);
	} else {
		entry->extra = 0;
	}

	/* desc */
	if (!*c) {
		/* This is a corner case where the named unit mask entry
		 * only has one word.  This should really be fixed in the
		 * unit_mask file */
		entry->desc = xstrdup(entry->name);
	} else
		entry->desc = xstrdup(c);
	return;

invalid_out:
	parse_error("invalid unit mask entry");
}


static struct op_unit_mask * new_unit_mask(void)
{
	struct op_unit_mask * um = xmalloc(sizeof(struct op_unit_mask));
	memset(um, '\0', sizeof(struct op_unit_mask));
	list_add_tail(&um->um_next, &um_list);

	return um;
}

static void free_unit_mask(struct op_unit_mask * um)
{
	list_del(&um->um_next);
	free(um);
	um = NULL;
}

/*
 * name:zero type:mandatory default:0x0
 * \t0x0 No unit mask
 */
static void read_unit_masks(char const * file)
{
	struct op_unit_mask * um = NULL;
	char * line;
	FILE * fp = fopen(file, "r");

	if (!fp) {
		fprintf(stderr,
			"oprofile: could not open unit mask description file %s\n", file);
		exit(EXIT_FAILURE);
	}

	filename = file;
	line_nr = 1;

	line = op_get_line(fp);

	while (line) {
		if (empty_line(line) || comment_line(line))
			goto next;

		if (line[0] != '\t') {
			um = new_unit_mask();
			parse_um(um, line);
		} else {
			if (!um)
				parse_error("no unit mask name line");

			parse_um_entry(&um->um[um->num], line);
			++(um->num);
		}

next:
		free(line);
		line = op_get_line(fp);
		++line_nr;
	}

	fclose(fp);
}


static u32 parse_counter_mask(char const * str)
{
	u32 mask = 0;
	char const * numstart = str;

	while (*numstart) {
		mask |= 1 << parse_int(numstart);

		while (*numstart && *numstart != ',')
			++numstart;
		/* skip , unless we reach eos */
		if (*numstart)
			++numstart;

		numstart = skip_ws(numstart);
	}

	return mask;
}

static struct op_unit_mask * try_find_um(char const * value)
{
	struct list_head * pos;

	list_for_each(pos, &um_list) {
		struct op_unit_mask * um = list_entry(pos, struct op_unit_mask, um_next);
		if (strcmp(value, um->name) == 0) {
			um->used = 1;
			return um;
		}
	}
	return NULL;
}

static struct op_unit_mask * find_um(char const * value)
{
	struct op_unit_mask * um = try_find_um(value);
	if (um)
		return um;
	fprintf(stderr, "oprofile: could not find unit mask %s\n", value);
	exit(EXIT_FAILURE);
}

/* um:a,b,c,d merge multiple unit masks */
static struct op_unit_mask * merge_um(char * value)
{
	int num;
	char *s;
	struct op_unit_mask *new, *um;
	enum unit_mask_type type = -1U;

	um = try_find_um(value);
	if (um)
		return um;

	new = new_unit_mask();
	new->name = xstrdup(value);
	new->used = 1;
	num = 0;
	while ((s = strsep(&value, ",")) != NULL) {
		unsigned c;
		um = find_um(s);
		if (type == -1U)
			type = um->unit_type_mask;
		if (um->unit_type_mask != type)
			parse_error("combined unit mask must be all the same types");
		if (type != utm_bitmask && type != utm_exclusive)
			parse_error("combined unit mask must be all bitmasks or exclusive");
		new->default_mask |= um->default_mask;
		new->num += um->num;
		if (new->num > MAX_UNIT_MASK)
			parse_error("too many members in combined unit mask");
		for (c = 0; c < um->num; c++, num++) {
			new->um[num] = um->um[c];
			new->um[num].desc = xstrdup(new->um[num].desc);
		}
	}
	if (type == -1U)
		parse_error("Empty unit mask");
	new->unit_type_mask = type;
	return new;
}

/* parse either a "tag:value" or a ": trailing description string" */
static int next_token(char const ** cp, char ** name, char ** value)
{
	size_t tag_len;
	size_t val_len;
	char const * c = *cp;
	char const * end;
	char const * colon;

	c = skip_ws(c);
	end = colon = c;
	end = skip_nonws(end);

	colon = strchr(colon, ':');

	if (!colon) {
		if (*c)
			parse_error("next_token(): garbage at end of line");
		return 0;
	}

	if (colon >= end)
		parse_error("next_token() expected ':'");

	tag_len = colon - c;
	val_len = end - (colon + 1);

	if (!tag_len) {
		/* : trailing description */
		end = skip_ws(end);
		*name = xstrdup("desc");
		*value = xstrdup(end);
		end += strlen(end);
	} else {
		/* tag:value */
		*name = op_xstrndup(c, tag_len);
		*value = op_xstrndup(colon + 1, val_len);
		end = skip_ws(end);
	}

	*cp = end;
	return 1;
}

static void include_events (char *value)
{
	char * event_file;
	const char *old_filename;
	int old_line_nr;

	event_file = build_fn(value, "events");
	old_line_nr = line_nr;
	old_filename = filename;
	read_events(event_file);
	line_nr = old_line_nr;
	filename = old_filename;
	free(event_file);
}

static struct op_event * new_event(void)
{
	struct op_event * event = xmalloc(sizeof(struct op_event));
	memset(event, '\0', sizeof(struct op_event));
	list_add_tail(&event->event_next, &events_list);

	return event;
}

static void free_event(struct op_event * event)
{
	list_del(&event->event_next);
	free(event);
}

/* event:0x00 counters:0 um:zero minimum:4096 name:ISSUES : Total issues */
/* event:0x00 ext:xxxxxx um:zero minimum:4096 name:ISSUES : Total issues */
static void read_events(char const * file)
{
	struct op_event * event = NULL;
	char * line;
	char * name;
	char * value;
	char const * c;
	int seen_event, seen_counters, seen_um, seen_minimum, seen_name, seen_ext;
	FILE * fp = fopen(file, "r");
	int tags;

	if (!fp) {
		fprintf(stderr, "oprofile: could not open event description file %s\n", file);
		exit(EXIT_FAILURE);
	}

	filename = file;
	line_nr = 1;

	line = op_get_line(fp);

	while (line) {
		if (empty_line(line) || comment_line(line))
			goto next;

		tags = 0;
		seen_name = 0;
		seen_event = 0;
		seen_counters = 0;
		seen_ext = 0;
		seen_um = 0;
		seen_minimum = 0;
		event = new_event();
		event->filter = -1;
		event->ext = NULL;

		c = line;
		while (next_token(&c, &name, &value)) {
			if (strcmp(name, "name") == 0) {
				if (seen_name)
					parse_error("duplicate name: tag");
				seen_name = 1;
				if (strchr(value, '/') != NULL)
					parse_error("invalid event name");
				if (strchr(value, '.') != NULL)
					parse_error("invalid event name");
				event->name = value;
			} else if (strcmp(name, "event") == 0) {
				if (seen_event)
					parse_error("duplicate event: tag");
				seen_event = 1;
				event->val = parse_hex(value);
				free(value);
			} else if (strcmp(name, "counters") == 0) {
				if (seen_counters)
					parse_error("duplicate counters: tag");
				seen_counters = 1;
				if (!strcmp(value, "cpuid"))
					event->counter_mask = arch_get_counter_mask();
				else
					event->counter_mask = parse_counter_mask(value);
				free(value);
			} else if (strcmp(name, "ext") == 0) {
				if (seen_ext)
					parse_error("duplicate ext: tag");
				seen_ext = 1;
				event->ext = value;
			} else if (strcmp(name, "um") == 0) {
				if (seen_um)
					parse_error("duplicate um: tag");
				seen_um = 1;
				if (strchr(value, ','))
					event->unit = merge_um(value);
				else
					event->unit = find_um(value);
				free(value);
			} else if (strcmp(name, "minimum") == 0) {
				if (seen_minimum)
					parse_error("duplicate minimum: tag");
				seen_minimum = 1;
				event->min_count = parse_int(value);
				free(value);
			} else if (strcmp(name, "desc") == 0) {
				event->desc = value;
			} else if (strcmp(name, "filter") == 0) {
				event->filter = parse_int(value);
				free(value);
			} else if (strcmp(name, "include") == 0) {
				if (tags > 0)
					parse_error("tags before include:");
				free_event(event);
				include_events(value);
				free(value);
				c = skip_ws(c);
				if (*c != '\0' && *c != '#')
					parse_error("non whitespace after include:");
				break;
			} else {
				parse_error("unknown tag");
			}
			tags++;

			free(name);
		}
next:
		free(line);
		line = op_get_line(fp);
		++line_nr;
	}

	fclose(fp);
}


/* usefull for make check */
static int check_unit_mask(struct op_unit_mask const * um,
	char const * cpu_name)
{
	u32 i;
	int err = 0;

	if (!um->used) {
		fprintf(stderr, "um %s is not used\n", um->name);
		err = EXIT_FAILURE;
	}

	if (um->unit_type_mask == utm_mandatory && um->num != 1) {
		fprintf(stderr, "mandatory um %s doesn't contain exactly one "
			"entry (%s)\n", um->name, cpu_name);
		err = EXIT_FAILURE;
	} else if (um->unit_type_mask == utm_bitmask) {
		u32 default_mask = um->default_mask;
		for (i = 0; i < um->num; ++i)
			default_mask &= ~um->um[i].value;

		if (default_mask) {
			fprintf(stderr, "um %s default mask is not valid "
				"(%s)\n", um->name, cpu_name);
			err = EXIT_FAILURE;
		}
	} else if (um->unit_type_mask == utm_exclusive) {
		if (um->default_mask_name) {
			for (i = 0; i < um->num; ++i) {
				if (0 == strcmp(um->default_mask_name,
						um->um[i].name))
					break;
			}
		} else {
			for (i = 0; i < um->num; ++i) {
				if (um->default_mask == um->um[i].value)
					break;
			}
		}

		if (i == um->num) {
			fprintf(stderr, "exclusive um %s default value is not "
				"valid (%s)\n", um->name, cpu_name);
			err = EXIT_FAILURE;
		}
	}
	return err;
}

static void arch_filter_events(op_cpu cpu_type)
{
	struct list_head * pos, * pos2;
	unsigned filter = arch_get_filter(cpu_type);
	if (!filter)
		return;
	list_for_each_safe (pos, pos2, &events_list) {
		struct op_event * event = list_entry(pos, struct op_event, event_next);
		if (event->filter >= 0 && ((1U << event->filter) & filter))
			delete_event(event);
	}
}

static void load_events_name(const char *cpu_name)
{
	char * event_file;
	char * um_file;

	event_file = build_fn(cpu_name, "events");
	um_file = build_fn(cpu_name, "unit_masks");

	read_unit_masks(um_file);
	read_events(event_file);

	free(um_file);
	free(event_file);
}

static void load_events(op_cpu cpu_type)
{
	const char * cpu_name = op_get_cpu_name(cpu_type);
	struct list_head * pos;
	struct op_event *event;
	struct op_unit_mask *unit_mask;
	int err = 0;

	if (!list_empty(&events_list))
		return;

	load_events_name(cpu_name);

	arch_filter_events(cpu_type);

	/* sanity check: all unit mask must be used */
	list_for_each(pos, &um_list) {
		struct op_unit_mask * um = list_entry(pos, struct op_unit_mask, um_next);
		err |= check_unit_mask(um, cpu_name);
	}
	if (err)
		exit(err);

	if (!op_cpu_has_timer_fs())
		return;

	/* sanity check: Don't use event `TIMER' since it is predefined.  */
	list_for_each(pos, &events_list) {
		struct op_event * event = list_entry(pos, struct op_event,
						     event_next);

		if (strcmp(event->name, TIMER_EVENT_NAME) == 0) {
			fprintf(stderr, "Error: " TIMER_EVENT_NAME
				" event cannot be redefined.\n");
			exit(EXIT_FAILURE);
		}
		if (event->val == TIMER_EVENT_VALUE) {
			fprintf(stderr, "Error: Event %s uses " TIMER_EVENT_NAME
				" which is reserverd for timer based sampling.\n",
				event->name);
			exit(EXIT_FAILURE);
		}
	}

	list_for_each(pos, &um_list) {
		struct op_unit_mask * um = list_entry(pos, struct op_unit_mask,
						      um_next);
		if (strcmp(um->name, TIMER_EVENT_UNIT_MASK_NAME) == 0) {
			fprintf(stderr, "Error: " TIMER_EVENT_UNIT_MASK_NAME
				" unit mask cannot be redefined.\n");
			exit(EXIT_FAILURE);
		}
	}

	unit_mask = new_unit_mask();
	unit_mask->name = xstrdup(TIMER_EVENT_UNIT_MASK_NAME);
	unit_mask->num = 1;
	unit_mask->unit_type_mask = utm_mandatory;
	unit_mask->um[0].extra = 0;
	unit_mask->um[0].value = 0;
	unit_mask->um[0].name = xstrdup("");
	unit_mask->um[0].desc = xstrdup("No unit mask");
	unit_mask->used = 1;

	event = new_event();
	event->name = xstrdup(TIMER_EVENT_NAME);
	event->desc = xstrdup(TIMER_EVENT_DESC);
	event->val = TIMER_EVENT_VALUE;
	event->unit = unit_mask;
	event->min_count = 0;
	event->filter = 0;
	event->counter_mask = 1 << (op_get_nr_counters(cpu_type) - 1);
	event->ext = NULL;
	event->filter = -1;
}

struct list_head * op_events(op_cpu cpu_type)
{
	load_events(cpu_type);
	arch_filter_events(cpu_type);
	return &events_list;
}


static void delete_unit_mask(struct op_unit_mask * unit)
{
	u32 cur;
	for (cur = 0 ; cur < unit->num ; ++cur) {
		if (unit->um[cur].desc)
			free(unit->um[cur].desc);
	}

	if (unit->name)
		free(unit->name);

	list_del(&unit->um_next);
	free(unit);
}


static void delete_event(struct op_event * event)
{
	if (event->name)
		free(event->name);
	if (event->desc)
		free(event->desc);

	list_del(&event->event_next);
	free(event);
}


void op_free_events(void)
{
	struct list_head * pos, * pos2;
	list_for_each_safe(pos, pos2, &events_list) {
		struct op_event * event = list_entry(pos, struct op_event, event_next);
		delete_event(event);
	}

	list_for_each_safe(pos, pos2, &um_list) {
		struct op_unit_mask * unit = list_entry(pos, struct op_unit_mask, um_next);
		delete_unit_mask(unit);
	}
}

/* There can be actually multiple events here, so this is not quite correct */
static struct op_event * find_event_any(u32 nr)
{
	struct list_head * pos;

	list_for_each(pos, &events_list) {
		struct op_event * event = list_entry(pos, struct op_event, event_next);
		if (event->val == nr)
			return event;
	}

	return NULL;
}

static struct op_event * find_event_um(u32 nr, u32 um)
{
	struct list_head * pos;
	unsigned int i;

	list_for_each(pos, &events_list) {
		struct op_event * event = list_entry(pos, struct op_event, event_next);
		if (event->val == nr) {
			for (i = 0; i < event->unit->num; i++) {
				if (event->unit->um[i].value == um)
					return event;
			}
		}
	}

	return NULL;
}

static FILE * open_event_mapping_file(char const * cpu_name)
{
	char * ev_map_file;
	char * dir;
	dir = getenv("OPROFILE_EVENTS_DIR");
	if (dir == NULL)
		dir = OP_DATADIR;

	ev_map_file = xmalloc(strlen(dir) + strlen("/") + strlen(cpu_name) +
	                    strlen("/") + + strlen("event_mappings") + 1);
	strcpy(ev_map_file, dir);
	strcat(ev_map_file, "/");

	strcat(ev_map_file, cpu_name);
	strcat(ev_map_file, "/");
	strcat(ev_map_file, "event_mappings");
	filename = ev_map_file;
	return (fopen(ev_map_file, "r"));
}


/**
 *  This function is PPC64-specific.
 */
static char const * get_mapping(u32 nr, FILE * fp)
{
	char * line;
	char * name;
	char * value;
	char const * c;
	char * map = NULL;
	int seen_event = 0, seen_mmcr0 = 0, seen_mmcr1 = 0, seen_mmcra = 0;
	u32 mmcr0 = 0;
	u64 mmcr1 = 0;
	u32 mmcra = 0;
	int event_found = 0;

	line_nr = 1;
	line = op_get_line(fp);
	while (line && !event_found) {
		if (empty_line(line) || comment_line(line))
			goto next;

		seen_event = 0;
		seen_mmcr0 = 0;
		seen_mmcr1 = 0;
		seen_mmcra = 0;
		mmcr0 = 0;
		mmcr1 = 0;
		mmcra = 0;

		c = line;
		while (next_token(&c, &name, &value)) {
			if (strcmp(name, "event") == 0) {
				u32 evt;
				if (seen_event)
					parse_error("duplicate event tag");
				seen_event = 1;
				evt = parse_hex(value);
				if (evt == nr)
					event_found = 1;
				free(value);
			} else if (strcmp(name, "mmcr0") == 0) {
				if (seen_mmcr0)
					parse_error("duplicate mmcr0 tag");
				seen_mmcr0 = 1;
				mmcr0 = parse_hex(value);
				free(value);
			} else if (strcmp(name, "mmcr1") == 0) {
				if (seen_mmcr1)
					parse_error("duplicate mmcr1: tag");
				seen_mmcr1 = 1;
				mmcr1 = parse_long_hex(value);
				free(value);
			} else if (strcmp(name, "mmcra") == 0) {
				if (seen_mmcra)
					parse_error("duplicate mmcra: tag");
				seen_mmcra = 1;
				mmcra = parse_hex(value);
				free(value);
			} else {
				parse_error("unknown tag");
			}

			free(name);
		}
next:
		free(line);
		line = op_get_line(fp);
		++line_nr;
	}
	if (event_found) {
		if (!seen_mmcr0 || !seen_mmcr1 || !seen_mmcra) {
			fprintf(stderr, "Error: Missing information in line %d of event mapping file %s\n", line_nr, filename);
			exit(EXIT_FAILURE);
		}
		map = xmalloc(70);
		snprintf(map, 70, "mmcr0:%u mmcr1:%Lu mmcra:%u",
		         mmcr0, mmcr1, mmcra);
	}

	return map;
}


char const * find_mapping_for_event(u32 nr, op_cpu cpu_type)
{
	char const * cpu_name = op_get_cpu_name(cpu_type);
	FILE * fp = open_event_mapping_file(cpu_name);
	char const * map = NULL;
	switch (cpu_type) {
		case CPU_PPC64_PA6T:
		case CPU_PPC64_970:
		case CPU_PPC64_970MP:
		case CPU_PPC64_POWER4:
		case CPU_PPC64_POWER5:
		case CPU_PPC64_POWER5p:
		case CPU_PPC64_POWER5pp:
		case CPU_PPC64_POWER6:
		case CPU_PPC64_POWER7:
		case CPU_PPC64_IBM_COMPAT_V1:
		// For ppc64 types of CPU_PPC64_ARCH_V1 and higher, we don't need an event_mappings file
			if (!fp) {
				fprintf(stderr, "oprofile: could not open event mapping file %s\n", filename);
				exit(EXIT_FAILURE);
			} else {
				map = get_mapping(nr, fp);
			}
			break;
		default:
			break;
	}

	if (fp)
		fclose(fp);

	return map;
}

static int match_event(int i, struct op_event *event, unsigned um)
{
	unsigned v = event->unit->um[i].value;

	switch (event->unit->unit_type_mask) {
	case utm_exclusive:
	case utm_mandatory:
		return v == um;

	case utm_bitmask:
		return (v & um) || (!v && v == 0);
	}

	abort();
}

struct op_event * find_event_by_name(char const * name, unsigned um, int um_valid)
{
	struct list_head * pos;

	list_for_each(pos, &events_list) {
		struct op_event * event = list_entry(pos, struct op_event, event_next);
		if (strcmp(event->name, name) == 0) {
			if (um_valid) {
				unsigned i;

				for (i = 0; i < event->unit->num; i++)
					if (match_event(i, event, um))
						return event;
				continue;
			}
			return event;
		}
	}

	return NULL;
}


static struct op_event * find_next_event(struct op_event * e)
{
	struct list_head * n;

	for (n = e->event_next.next; n != &events_list; n = n->next) {
		struct op_event * ne = list_entry(n, struct op_event, event_next);
		if (!strcmp(e->name, ne->name))
			return ne;
	}
	return NULL;
}

struct op_event * op_find_event(op_cpu cpu_type, u32 nr, u32 um)
{
	struct op_event * event;

	load_events(cpu_type);

	event = find_event_um(nr, um);

	return event;
}

struct op_event * op_find_event_any(op_cpu cpu_type, u32 nr)
{
	load_events(cpu_type);

	return find_event_any(nr);
}

static int _is_um_valid_bitmask(struct op_event * event, u32 passed_um)
{
	int duped_um[MAX_UNIT_MASK];
	int retval = 0;
	u32 masked_val = 0;
	u32 i, k;
	int dup_value_used = 0;

	struct op_event evt;
	struct op_unit_mask * tmp_um = xmalloc(sizeof(struct op_unit_mask));
	struct op_unit_mask * tmp_um_no_dups = xmalloc(sizeof(struct op_unit_mask));
	memset(tmp_um, '\0', sizeof(struct op_unit_mask));;
	memset(tmp_um_no_dups, '\0', sizeof(struct op_unit_mask));
	memset(duped_um, '\0', sizeof(int) * MAX_UNIT_MASK);

	// First, we make a copy of the event, with just its unit mask values.
	evt.unit = tmp_um;
	evt.unit->num = event->unit->num;
	for (i = 0; i < event->unit->num; i++)
		evt.unit->um[i].value = event->unit->um[i].value;

	// Next, we sort the unit mask values in ascending order.
	for (i = 1; i < evt.unit->num; i++) {
		int j = i - 1;
		u32 tmp = evt.unit->um[i].value;
		while (j >= 0 && tmp < evt.unit->um[j].value) {
			evt.unit->um[j + 1].value = evt.unit->um[j].value;
			j -= 1;
		}
		evt.unit->um[j + 1].value = tmp;
	}

	/* Now we remove duplicates. Duplicate unit mask values were not
	 * allowed until the "named unit mask" support was added in
	 * release 0.9.7.  The down side to this is that if the user passed
	 * a unit mask value that includes one of the duplicated values,
	 * we have no way of differentiating between the duplicates, so
	 * the meaning of the bitmask would be ambiguous if we were to
	 * allow it.  Thus, we must prevent the user from specifying such
	 * bitmasks.
	 */
	for (i = 0, k = 0; k < evt.unit->num; i++) {
		tmp_um_no_dups->um[i].value = evt.unit->um[k].value;
		tmp_um_no_dups->num++;
		k++;
		while ((evt.unit->um[i].value == evt.unit->um[k].value) && i < evt.unit->num) {
			k++;
			duped_um[i] = 1;
		}
	}
	evt.unit = tmp_um_no_dups;

	// Now check if passed um==0 and if the defined event has a UM with value '0'.
	if (!passed_um) {
		for (i = 0; i < evt.unit->num; i++) {
			if (!evt.unit->um[i].value)
				return 1;
		}
	}

	/* Finally, we'll see if the passed unit mask value can be matched with a
	 * mask of available unit mask values. We check for this by determining
	 * whether the exact bits set in the current um are also set in the
	 * passed um; if so, we OR those bits into a cumulative masked_val variable.
	 * Simultaneously, we check if the passed um contains a non-unique unit
	 * mask value, in which case, it's invalid..
	 */
	for (i = 0; i < evt.unit->num; i++) {
		if ((evt.unit->um[i].value & passed_um) == evt.unit->um[i].value) {
			masked_val |= evt.unit->um[i].value;
			if (duped_um[i]) {
				dup_value_used = 1;
				break;
			}
		}
	}

	if (dup_value_used) {
		fprintf(stderr, "Ambiguous bitmask: Unit mask values"
		        " cannot include non-unique numerical values (i.e., 0x%x).\n",
		        evt.unit->um[i].value);
		fprintf(stderr, "Use ophelp to see the unit mask values for event %s.\n",
		        event->name);
	} else if (masked_val == passed_um && passed_um != 0) {
		retval = 1;
	}
	free(tmp_um);
	free(tmp_um_no_dups);
	return retval;
}

int op_check_events(int ctr, u32 nr, u32 um, op_cpu cpu_type)
{
	int ret = OP_INVALID_EVENT;
	size_t i;
	u32 ctr_mask = 1 << ctr;
	struct list_head * pos;

	load_events(cpu_type);

	list_for_each(pos, &events_list) {
		struct op_event * event = list_entry(pos, struct op_event, event_next);
		if (event->val != nr)
			continue;

		ret = OP_OK_EVENT;

		if ((event->counter_mask & ctr_mask) == 0)
			ret |= OP_INVALID_COUNTER;

		if (event->unit->unit_type_mask == utm_bitmask) {
			if (!_is_um_valid_bitmask(event, um))
				ret |= OP_INVALID_UM;
		} else {
			for (i = 0; i < event->unit->num; ++i) {
				if (event->unit->um[i].value == um)
					break;
			}
			if (i == event->unit->num)
				ret |= OP_INVALID_UM;
		}

		if (ret == OP_OK_EVENT)
			return ret;
	}

	return ret;
}


void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr)
{
	descr->name = "";
	descr->um = 0x0;
	/* A fixed value of CPU cycles; this should ensure good
	 * granulity even on faster CPUs, though it will generate more
	 * interrupts.
	 */
	descr->count = 100000;

	switch (cpu_type) {
		case CPU_PPRO:
		case CPU_PII:
		case CPU_PIII:
		case CPU_P6_MOBILE:
		case CPU_CORE:
		case CPU_CORE_2:
		case CPU_ATHLON:
		case CPU_HAMMER:
		case CPU_FAMILY10:
		case CPU_ARCH_PERFMON:
		case CPU_FAMILY11H:
 		case CPU_ATOM:
 		case CPU_CORE_I7:
		case CPU_NEHALEM:
		case CPU_HASWELL:
		case CPU_WESTMERE:
		case CPU_SANDYBRIDGE:
		case CPU_IVYBRIDGE:
		case CPU_MIPS_LOONGSON2:
		case CPU_FAMILY12H:
		case CPU_FAMILY14H:
		case CPU_FAMILY15H:
		case CPU_AMD64_GENERIC:
			descr->name = "CPU_CLK_UNHALTED";
			break;

		case CPU_RTC:
			descr->name = "RTC_INTERRUPTS";
			descr->count = 1024;
			break;

		case CPU_P4:
		case CPU_P4_HT2:
			descr->name = "GLOBAL_POWER_EVENTS";
			descr->um = 0x1;
			break;

		case CPU_IA64:
		case CPU_IA64_1:
		case CPU_IA64_2:
			descr->count = 1000000;
			descr->name = "CPU_CYCLES";
			break;

		case CPU_AXP_EV4:
		case CPU_AXP_EV5:
		case CPU_AXP_PCA56:
		case CPU_AXP_EV6:
		case CPU_AXP_EV67:
			descr->name = "CYCLES";
			break;

		// we could possibly use the CCNT
		case CPU_ARM_XSCALE1:
		case CPU_ARM_XSCALE2:
		case CPU_ARM_MPCORE:
		case CPU_ARM_V6:
		case CPU_ARM_V7:
		case CPU_ARM_V7_CA5:
		case CPU_ARM_V7_CA7:
		case CPU_ARM_V7_CA9:
		case CPU_ARM_V7_CA15:
		case CPU_AVR32:
		case CPU_ARM_SCORPION:
		case CPU_ARM_SCORPIONMP:
			descr->name = "CPU_CYCLES";
			break;

		case CPU_PPC64_PA6T:
		case CPU_PPC64_970:
		case CPU_PPC64_970MP:
		case CPU_PPC_7450:
		case CPU_PPC64_POWER4:
		case CPU_PPC64_POWER5:
		case CPU_PPC64_POWER6:
		case CPU_PPC64_POWER5p:
		case CPU_PPC64_POWER5pp:
		case CPU_PPC64_CELL:
		case CPU_PPC64_POWER7:
		case CPU_PPC64_IBM_COMPAT_V1:
		case CPU_PPC64_ARCH_V1:
		case CPU_PPC64_POWER8:
			descr->name = "CYCLES";
			break;

		case CPU_MIPS_20K:
			descr->name = "CYCLES";
			break;

		case CPU_MIPS_24K:
		case CPU_MIPS_34K:
		case CPU_MIPS_74K:
		case CPU_MIPS_1004K:
			descr->name = "INSTRUCTIONS";
			break;

		case CPU_MIPS_5K:
		case CPU_MIPS_25K:
			descr->name = "CYCLES";
			break;

		case CPU_MIPS_R10000:
		case CPU_MIPS_R12000:
			descr->name = "INSTRUCTIONS_GRADUATED";
			break;

		case CPU_MIPS_RM7000:
		case CPU_MIPS_RM9000:
			descr->name = "INSTRUCTIONS_ISSUED";
			break;

		case CPU_MIPS_SB1:
			descr->name = "INSN_SURVIVED_STAGE7";
			break;

		case CPU_MIPS_VR5432:
		case CPU_MIPS_VR5500:
			descr->name = "INSTRUCTIONS_EXECUTED";
			break;

		case CPU_PPC_E500:
		case CPU_PPC_E500_2:
		case CPU_PPC_E300:
			descr->name = "CPU_CLK";
			break;

		case CPU_S390_Z10:
		case CPU_S390_Z196:
		case CPU_S390_ZEC12:
 			if (op_get_nr_counters(cpu_type) > 1) {
 				descr->name = "HWSAMPLING";
 				descr->count = 4127518;
 			} else {
 				descr->name = TIMER_EVENT_NAME;
 				descr->count = 10000;
 			}
  			break;

		case CPU_TILE_TILE64:
		case CPU_TILE_TILEPRO:
		case CPU_TILE_TILEGX:
			descr->name = "ONE";
			break;

		// don't use default, if someone add a cpu he wants a compiler
		// warning if he forgets to handle it here.
		case CPU_TIMER_INT:
		case CPU_NO_GOOD:
		case MAX_CPU_TYPE:
			break;
	}
}

static void extra_check(struct op_event *e, char *name, unsigned w)
{
	int found;
	unsigned i;

	if (!e->unit->um[w].extra) {
		fprintf(stderr,
			"Named unit mask (%s) not allowed for event without 'extra:' values.\n"
			"Please specify the numerical value for the unit mask. See 'opcontrol'\n"
			"or 'operf' man page for more info.\n", name);
		exit(EXIT_FAILURE);
	}

	found = 0;
	for (i = 0; i < e->unit->num; i++) {
		int len = strcspn(e->unit->um[i].desc, " \t");
		if (!strncmp(name, e->unit->um[i].desc, len) &&
		    name[len] == '\0')
			found++;
	}

	if (found > 1) {
		fprintf(stderr,
			"Unit mask name `%s' not unique. Please use a numerical unit mask\n", name);
		exit(EXIT_FAILURE);
	}
}

static void do_resolve_unit_mask(struct op_event *e,
	struct parsed_event *pe, u32 *extra)
{
	unsigned i;

	/* If not specified um and the default um is name type
	 * we populate pe unitmask name with default name */
	if ((e->unit->default_mask_name != NULL) &&
			(pe->unit_mask_name == NULL) && (!pe->unit_mask_valid)) {
		pe->unit_mask_name = xstrdup(e->unit->default_mask_name);
	}

	for (;;) {
		if (pe->unit_mask_name == NULL) {
			/* For numerical unit mask */
			int found = 0;

			/* Use default unitmask if not specified */
			if (!pe->unit_mask_valid) {
				pe->unit_mask_valid = 1;
				pe->unit_mask = e->unit->default_mask;
			}

			/* Checking to see there are any duplicate numerical unit mask
			 * in which case it should be using named unit mask instead.
			 */
			for (i = 0; i < e->unit->num; i++) {
				if (e->unit->um[i].value == (unsigned int)pe->unit_mask)
					found++;
			}
			if (found > 1) {
				fprintf(stderr, "Unit mask (0x%x) is non unique.\n"
				        "Please specify the unit mask using the first "
					"word of the description\n",
					pe->unit_mask);
				exit(EXIT_FAILURE);
			}

			if (i == e->unit->num) {
				e = find_next_event(e);
				if (e != NULL)
					continue;
			}
			return;
		} else {
			/* For named unit mask */
			for (i = 0; i < e->unit->num; i++) {
				int len = 0;

				if (e->unit->um[i].name)
					len = strlen(e->unit->um[i].name);

				if (len
				&&  (!strncmp(pe->unit_mask_name,
					      e->unit->um[i].name, len))
				&&  (pe->unit_mask_name[len] == '\0'))
					break;
			}
			if (i == e->unit->num) {
				e = find_next_event(e);
				if (e != NULL)
					continue;
				fprintf(stderr, "Cannot find unit mask %s for %s\n",
					pe->unit_mask_name, pe->name);
				exit(EXIT_FAILURE);
			}
			extra_check(e, pe->unit_mask_name, i);
			pe->unit_mask_valid = 1;
			pe->unit_mask = e->unit->um[i].value;
			if (extra) {
				if (e->unit->um[i].extra == EXTRA_NONE)
					*extra = e->unit->um[i].value;
				else
					*extra = e->unit->um[i].extra;
			}
			return;
		}
	}
}

void op_resolve_unit_mask(struct parsed_event *pe, u32 *extra)
{
	struct op_event *e;

	e = find_event_by_name(pe->name, 0, 0);
	if (!e) {
		fprintf(stderr, "Cannot find event %s\n", pe->name);
		exit(EXIT_FAILURE);
	}
	return do_resolve_unit_mask(e, pe, extra);
}
