/*
 * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
 * Copyright (c) 2006 IBM Corp.
 * Contributed by Kevin Corry <kevcorry@us.ibm.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * pfmlib_intel_netburst.c
 *
 * Support for the Pentium4/Xeon/EM64T processor family (family=15).
 */
/* private headers */
#include "pfmlib_priv.h"
#include "pfmlib_intel_netburst_priv.h"
#include "pfmlib_intel_x86_priv.h"
#include "events/intel_netburst_events.h"

const pfmlib_attr_desc_t netburst_mods[]={
	PFM_ATTR_B("u", "monitor at priv level 1, 2, 3"),	/* monitor priv level 1, 2, 3 */
	PFM_ATTR_B("k", "monitor at priv level 0"),		/* monitor priv level 0 */
	PFM_ATTR_B("cmpl", "complement"),			/* set: <=, clear: > */
	PFM_ATTR_B("e", "edge"),				/* edge */
	PFM_ATTR_I("thr", "event threshold in range [0-15]"),	/* threshold */
};
#define NETBURST_MODS_COUNT (sizeof(netburst_mods)/sizeof(pfmlib_attr_desc_t))


extern pfmlib_pmu_t netburst_support;

static inline int
netburst_get_numasks(int pidx)
{
	int i = 0;
	/*
	 * name = NULL is end-marker
	 */
	while (netburst_events[pidx].event_masks[i].name)
		i++;
	return i;
}

static void
netburst_display_reg(pfmlib_event_desc_t *e)
{
	netburst_escr_value_t escr;
	netburst_cccr_value_t cccr;

	escr.val = e->codes[0];
	cccr.val = e->codes[1];

	__pfm_vbprintf("[0x%"PRIx64" 0x%"PRIx64" 0x%"PRIx64" usr=%d os=%d tag_ena=%d tag_val=%d "
		       "evmask=0x%x evsel=0x%x escr_sel=0x%x comp=%d cmpl=%d thr=%d e=%d",
			escr,
			cccr,
			e->codes[2], /* perf_event code */
			escr.bits.t0_usr, /* t1 is identical */
			escr.bits.t0_os,  /* t1 is identical */
			escr.bits.tag_enable,
			escr.bits.tag_value,
			escr.bits.event_mask,
			escr.bits.event_select,
			cccr.bits.escr_select,
			cccr.bits.compare,
			cccr.bits.complement,
			cccr.bits.threshold,
			cccr.bits.edge);

	__pfm_vbprintf("] %s\n", e->fstr);
}

static int
netburst_add_defaults(pfmlib_event_desc_t *e, unsigned int *evmask)
{
	int i, n;

	n = netburst_get_numasks(e->event);

	for (i = 0; i < n; i++) {

		if (netburst_events[e->event].event_masks[i].flags & NETBURST_FL_DFL)
			goto found;
	}
	return PFM_ERR_ATTR;
found:
	*evmask = 1 << netburst_events[e->event].event_masks[i].bit;
	n = e->nattrs;
	e->attrs[n].id = i;
	e->attrs[n].ival = i;
	e->nattrs = n+1;

	return PFM_SUCCESS;
}

int
pfm_netburst_get_encoding(void *this, pfmlib_event_desc_t *e)
{
	pfm_event_attr_info_t *a;
	netburst_escr_value_t escr;
	netburst_cccr_value_t cccr;
	unsigned int evmask = 0;
	unsigned int plmmsk = 0;
	int umask_done = 0;
	const char *n;
	int k, id, bit, ret;
	int tag_enable = 0, tag_value = 0;

	e->fstr[0] = '\0';

	escr.val = 0;
	cccr.val = 0;

	for(k=0; k < e->nattrs; k++) {
		a = attr(e, k);

		if (a->ctrl != PFM_ATTR_CTRL_PMU)
			continue;

		if (a->type == PFM_ATTR_UMASK) {

			bit = netburst_events[e->event].event_masks[a->idx].bit;
			n   = netburst_events[e->event].event_masks[a->idx].name;
			/*
			 * umask combination seems possible, although it does
			 * not always make sense, e.g., BOGUS vs. NBOGUS
			 */
			if (bit < EVENT_MASK_BITS && n) {
				evmask |= (1 << bit);
			} else	if (bit >= EVENT_MASK_BITS && n) {
				tag_value |= (1 << (bit - EVENT_MASK_BITS));
				tag_enable = 1;
			}
			umask_done = 1;
		} else if (a->type == PFM_ATTR_RAW_UMASK) {
			/* should not happen */
			return PFM_ERR_ATTR;
		} else {
			uint64_t ival = e->attrs[k].ival;
			switch (a->idx) {
			case NETBURST_ATTR_U:
				escr.bits.t1_usr = !!ival;
				escr.bits.t0_usr = !!ival;
				plmmsk |= _NETBURST_ATTR_U;
				break;
			case NETBURST_ATTR_K:
				escr.bits.t1_os = !!ival;
				escr.bits.t0_os = !!ival;
				plmmsk |= _NETBURST_ATTR_K;
				break;
			case NETBURST_ATTR_E:
				if (ival) {
					cccr.bits.compare = 1;
					cccr.bits.edge = 1;
				}
				break;
			case NETBURST_ATTR_C:
				if (ival) {
					cccr.bits.compare = 1;
					cccr.bits.complement = 1;
				}
				break;
			case NETBURST_ATTR_T:
				if (ival > 15)
					return PFM_ERR_ATTR_VAL;

				if (ival) {
					cccr.bits.compare = 1;
					cccr.bits.threshold = ival;
				}
				break;
			default:
				return PFM_ERR_ATTR;
			}
		}
	}
	/*
	 * handle case where no priv level mask was passed.
	 * then we use the dfl_plm
	 */
	if (!(plmmsk & (_NETBURST_ATTR_K|_NETBURST_ATTR_U))) {
		if (e->dfl_plm & PFM_PLM0) {
			escr.bits.t1_os = 1;
			escr.bits.t0_os = 1;
		}
		if (e->dfl_plm & PFM_PLM3) {
			escr.bits.t1_usr = 1;
			escr.bits.t0_usr = 1;
		}
	}

	if (!umask_done) {
		ret = netburst_add_defaults(e, &evmask);
		if (ret != PFM_SUCCESS)
			return ret;
	}

	escr.bits.tag_enable   = tag_enable;
	escr.bits.tag_value    = tag_value;
	escr.bits.event_mask   = evmask;
	escr.bits.event_select = netburst_events[e->event].event_select;


	cccr.bits.enable        = 1;
	cccr.bits.escr_select   = netburst_events[e->event].escr_select;
	cccr.bits.active_thread = 3;

	if (e->event == PME_REPLAY_EVENT)
		escr.bits.event_mask &= P4_REPLAY_REAL_MASK;	 /* remove virtual mask bits */

	/*
	 * reorder all the attributes such that the fstr appears always
	 * the same regardless of how the attributes were submitted.
	 */
	evt_strcat(e->fstr, "%s", netburst_events[e->event].name);
	pfmlib_sort_attr(e);
	for(k=0; k < e->nattrs; k++) {
		a = attr(e, k);
		if (a->ctrl != PFM_ATTR_CTRL_PMU)
			continue;
		if (a->type == PFM_ATTR_UMASK) {
			id = e->attrs[k].id;
			evt_strcat(e->fstr, ":%s", netburst_events[e->event].event_masks[id].name);
		}
	}

	evt_strcat(e->fstr, ":%s=%lu", netburst_mods[NETBURST_ATTR_K].name, escr.bits.t0_os);
	evt_strcat(e->fstr, ":%s=%lu", netburst_mods[NETBURST_ATTR_U].name, escr.bits.t0_usr);
	evt_strcat(e->fstr, ":%s=%lu", netburst_mods[NETBURST_ATTR_E].name, cccr.bits.edge);
	evt_strcat(e->fstr, ":%s=%lu", netburst_mods[NETBURST_ATTR_C].name, cccr.bits.complement);
	evt_strcat(e->fstr, ":%s=%lu", netburst_mods[NETBURST_ATTR_T].name, cccr.bits.threshold);

	e->count = 2;
	e->codes[0] = escr.val;
	e->codes[1] = cccr.val;

	netburst_display_reg(e);

	return PFM_SUCCESS;
}

static int
pfm_netburst_detect(void *this)
{
	int ret;
	int model;

	ret = pfm_intel_x86_detect();
	if (ret != PFM_SUCCESS)
		return ret;

	if (pfm_intel_x86_cfg.family != 15)
		return PFM_ERR_NOTSUPP;

	model = pfm_intel_x86_cfg.model;
	if (model == 3 || model == 4 || model == 6)
		return PFM_ERR_NOTSUPP;

	return PFM_SUCCESS;
}

static int
pfm_netburst_detect_prescott(void *this)
{
	int ret;
	int model;

	ret = pfm_intel_x86_detect();
	if (ret != PFM_SUCCESS)
		return ret;

	if (pfm_intel_x86_cfg.family != 15)
		return PFM_ERR_NOTSUPP;

	/*
	 * prescott has one more event (instr_completed)
	 */
	model = pfm_intel_x86_cfg.model;
	if (model != 3 && model != 4 && model != 6)
		return PFM_ERR_NOTSUPP;

	return PFM_SUCCESS;
}

static int
pfm_netburst_get_event_first(void *this)
{
	pfmlib_pmu_t *p = this;
	return p->pme_count ? 0 : -1;
}

static int
pfm_netburst_get_event_next(void *this, int idx)
{
	pfmlib_pmu_t *p = this;

	if (idx >= (p->pme_count-1))
		return -1;

	return idx+1;
}

static int
pfm_netburst_event_is_valid(void *this, int pidx)
{
	pfmlib_pmu_t *p = this;
	return pidx >= 0 && pidx < p->pme_count;
}

static int
pfm_netburst_get_event_attr_info(void *this, int pidx, int attr_idx, pfm_event_attr_info_t *info)
{
	const netburst_entry_t *pe = this_pe(this);
	int numasks, idx;

	numasks = netburst_get_numasks(pidx);
	if (attr_idx < numasks) {
		//idx = pfm_intel_x86_attr2umask(this, pidx, attr_idx);
		idx = attr_idx;
		info->name = pe[pidx].event_masks[idx].name;
		info->desc = pe[pidx].event_masks[idx].desc;
		info->equiv= NULL;
		info->code = pe[pidx].event_masks[idx].bit;
		info->type = PFM_ATTR_UMASK;
		info->is_dfl = !!(pe[pidx].event_masks[idx].flags & NETBURST_FL_DFL);
	} else {
		idx = attr_idx - numasks;
		info->name = netburst_mods[idx].name;
		info->desc = netburst_mods[idx].desc;
		info->equiv= NULL;
		info->code = idx;
		info->type = netburst_mods[idx].type;
		info->is_dfl = 0;
	}
	info->ctrl = PFM_ATTR_CTRL_PMU;
	info->idx = idx; /* namespace specific index */
	info->dfl_val64 = 0;

	return PFM_SUCCESS;
}

static int
pfm_netburst_get_event_info(void *this, int idx, pfm_event_info_t *info)
{
	const netburst_entry_t *pe = this_pe(this);
	pfmlib_pmu_t *pmu = this;

	/*
	 * pmu and idx filled out by caller
	 */
	info->name  = pe[idx].name;
	info->desc  = pe[idx].desc;
	info->code  = pe[idx].event_select | (pe[idx].escr_select << 8);
	info->equiv = NULL;
	info->idx   = idx; /* private index */
	info->pmu   = pmu->pmu;

	info->nattrs  = netburst_get_numasks(idx);
	info->nattrs += NETBURST_MODS_COUNT;

	return PFM_SUCCESS;
}

static int
pfm_netburst_validate_table(void *this, FILE *fp)
{
	pfmlib_pmu_t *pmu = this;
	const netburst_entry_t *pe = netburst_events;
	const char *name =  pmu->name;
	int i, j, noname, ndfl;
	int error = 0;

	for(i=0; i < pmu->pme_count; i++) {

		if (!pe[i].name) {
			fprintf(fp, "pmu: %s event%d: :: no name (prev event was %s)\n", pmu->name, i,
			i > 1 ? pe[i-1].name : "??");
			error++;
		}

		if (!pe[i].desc) {
			fprintf(fp, "pmu: %s event%d: %s :: no description\n", name, i, pe[i].name);
			error++;
		}

		noname = ndfl = 0;

		/* name = NULL is end-marker, veryfy there is at least one */
		for(j= 0; j < EVENT_MASK_BITS; j++) {

			if (!pe[i].event_masks[j].name)
				noname++;

			if (pe[i].event_masks[j].name) {
				if (!pe[i].event_masks[j].desc) {
					fprintf(fp, "pmu: %s event%d:%s umask%d: %s :: no description\n", name, i, pe[i].name, j, pe[i].event_masks[j].name);
					error++;
				}
				if (pe[i].event_masks[j].bit >= (EVENT_MASK_BITS+4)) {
					fprintf(fp, "pmu: %s event%d:%s umask%d: %s :: invalid bit field\n", name, i, pe[i].name, j, pe[i].event_masks[j].name);
					error++;
				}

				if (pe[i].event_masks[j].flags & NETBURST_FL_DFL)
					ndfl++;
			}
		}
		if (ndfl > 1) {
			fprintf(fp, "pmu: %s event%d:%s :: more than one default umask\n", name, i, pe[i].name);
			error++;
		}
		if (!noname) {
			fprintf(fp, "pmu: %s event%d:%s :: no event mask end-marker\n", name, i, pe[i].name);
			error++;
		}
	}
	return error ? PFM_ERR_INVAL : PFM_SUCCESS;
}


static unsigned int
pfm_netburst_get_event_nattrs(void *this, int pidx)
{
	unsigned int nattrs;
	nattrs  = netburst_get_numasks(pidx);
	nattrs += NETBURST_MODS_COUNT;
	return nattrs;
}


pfmlib_pmu_t netburst_support = {
	.desc			= "Pentium4",
	.name			= "netburst",
	.pmu			= PFM_PMU_INTEL_NETBURST,
	.pme_count		= LIBPFM_ARRAY_SIZE(netburst_events) - 1,
	.type			= PFM_PMU_TYPE_CORE,
	.supported_plm		= INTEL_X86_PLM,
	.atdesc			= netburst_mods,
	.pe			= netburst_events,
	.max_encoding		= 3,
	.num_cntrs		= 18,

	.pmu_detect		= pfm_netburst_detect,
	.get_event_encoding[PFM_OS_NONE] = pfm_netburst_get_encoding,
	 PFMLIB_ENCODE_PERF(pfm_netburst_get_perf_encoding),
	.get_event_first	= pfm_netburst_get_event_first,
	.get_event_next		= pfm_netburst_get_event_next,
	.event_is_valid		= pfm_netburst_event_is_valid,
	.validate_table		= pfm_netburst_validate_table,
	.get_event_info		= pfm_netburst_get_event_info,
	.get_event_attr_info	= pfm_netburst_get_event_attr_info,
	.get_event_nattrs	= pfm_netburst_get_event_nattrs,
	 PFMLIB_VALID_PERF_PATTRS(pfm_netburst_perf_validate_pattrs),
};

pfmlib_pmu_t netburst_p_support = {
	.desc			= "Pentium4 (Prescott)",
	.name			= "netburst_p",
	.pmu			= PFM_PMU_INTEL_NETBURST_P,
	.pme_count		= LIBPFM_ARRAY_SIZE(netburst_events),
	.type			= PFM_PMU_TYPE_CORE,
	.supported_plm		= INTEL_X86_PLM,
	.atdesc			= netburst_mods,
	.pe			= netburst_events,
	.max_encoding		= 3,
	.num_cntrs		= 18,

	.pmu_detect		= pfm_netburst_detect_prescott,
	.get_event_encoding[PFM_OS_NONE] = pfm_netburst_get_encoding,
	 PFMLIB_ENCODE_PERF(pfm_netburst_get_perf_encoding),
	.get_event_first	= pfm_netburst_get_event_first,
	.get_event_next		= pfm_netburst_get_event_next,
	.event_is_valid		= pfm_netburst_event_is_valid,
	.validate_table		= pfm_netburst_validate_table,
	.get_event_info		= pfm_netburst_get_event_info,
	.get_event_attr_info	= pfm_netburst_get_event_attr_info,
	.get_event_nattrs	= pfm_netburst_get_event_nattrs,
	 PFMLIB_VALID_PERF_PATTRS(pfm_netburst_perf_validate_pattrs),
};
