/**
 * @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;

	v = 0;
	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 {
			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;
			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=... (M)odified cache state */
static void parse_um_entry(struct op_described_um * entry, char const * line)
{
	char const * c = line;

	c = skip_ws(c);
	entry->value = parse_hex(c);
	c = skip_nonws(c);

	c = skip_ws(c);
	if (strisprefix(c, "extra:")) {
		c += 6;
		entry->extra = parse_extra(c);
		c = skip_nonws(c);
	} else
		entry->extra = 0;

	if (!*c)
		parse_error("invalid unit mask entry");

	c = skip_ws(c);

	if (!*c)
		parse_error("invalid unit mask entry");

	entry->desc = xstrdup(c);
}


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);
}

/*
 * 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");
			if (um->num >= MAX_UNIT_MASK)
				parse_error("oprofile: maximum unit mask entries exceeded");

			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:");
			} 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 {
		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;
	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);
}

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:
			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);
}

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) {
			for (i = 0; i < event->unit->num; ++i)
				um &= ~(event->unit->um[i].value);			
			
			if (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_WESTMERE:
		case CPU_SANDYBRIDGE:
		case CPU_MIPS_LOONGSON2:
		case CPU_FAMILY12H:
		case CPU_FAMILY14H:
		case CPU_FAMILY15H:
			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_CA9:
		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:
			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;

		// 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, u32 unit_mask)
{
	unsigned i;
	int found = 0;

	for (i = 0; i < e->unit->num; i++)
		if (e->unit->um[i].value == unit_mask)
			found++;
	if (found > 1) {
		fprintf(stderr,
"Named unit masks not allowed for events without 'extra:' values.\n"
"Please specify the numerical value for the unit mask. See 'opcontrol'"
" man page for more info.\n");
		exit(EXIT_FAILURE);
	}
}

static void another_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'"
" 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. Sorry 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;
	int found;

	for (;;) {
		if (pe->unit_mask_name == NULL) {
			int fi = 0;
			unsigned um = pe->unit_mask;
			int had_unit_mask = pe->unit_mask_valid;

			found = 0;
			for (i = 0; i < e->unit->num; i++) {
			        if (pe->unit_mask_valid &&
				    e->unit->um[i].value == um) {
					if (found++ == 0)
						fi = i;
				}
				if (!pe->unit_mask_valid &&
				e->unit->um[i].value == e->unit->default_mask) {
					pe->unit_mask_valid = 1;
					pe->unit_mask = e->unit->default_mask;
					break;
				}
			}
			if (found > 1 && had_unit_mask) {
				fprintf(stderr,
	"Non unique numerical unit mask.\n"
	"Please specify the unit mask using the first word of the description\n");
				exit(EXIT_FAILURE);
			}
			extra_check(e, pe->unit_mask);
			if (i == e->unit->num) {
				e = find_next_event(e);
				if (e != NULL)
					continue;
			} else {
				if (extra)
					*extra = e->unit->um[i].extra;
			}
			return;
		}
		for (i = 0; i < e->unit->num; i++) {
			int len = strcspn(e->unit->um[i].desc, " \t");
			if (!strncmp(pe->unit_mask_name, e->unit->um[i].desc,
				    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);
		}
		another_extra_check(e, pe->unit_mask_name, i);
		pe->unit_mask_valid = 1;
		pe->unit_mask = e->unit->um[i].value;
		if (extra)
			*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);
}
