/*
 * pfmlib_intel_snbep_unc.c : Intel SandyBridge-EP uncore PMU common code
 *
 * Copyright (c) 2012 Google, Inc
 * Contributed by Stephane Eranian <eranian@gmail.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.
 */
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

/* private headers */
#include "pfmlib_priv.h"
#include "pfmlib_intel_x86_priv.h"
#include "pfmlib_intel_snbep_unc_priv.h"

const pfmlib_attr_desc_t snbep_unc_mods[]={
	PFM_ATTR_B("e", "edge detect"),			/* edge */
	PFM_ATTR_B("i", "invert"),			/* invert */
	PFM_ATTR_I("t", "threshold in range [0-255]"),	/* threshold */
	PFM_ATTR_I("t", "threshold in range [0-31]"),	/* threshold */
	PFM_ATTR_I("tf", "thread id filter [0-1]"),	/* thread id */
	PFM_ATTR_I("cf", "core id filter, includes non-thread data in bit 4 [0-15]"),	/* core id (ivbep) */
	PFM_ATTR_I("nf", "node id bitmask filter [0-255]"),/* nodeid mask filter0 */
	PFM_ATTR_I("ff", "frequency >= 100Mhz * [0-255]"),/* freq filter */
	PFM_ATTR_I("addr", "physical address matcher [40 bits]"),/* address matcher */
	PFM_ATTR_I("nf", "node id bitmask filter [0-255]"),/* nodeid mask filter1 */
	PFM_ATTR_B("isoc", "match isochronous requests"),   /* isochronous */
	PFM_ATTR_B("nc", "match non-coherent requests"),   /* non-coherent */
	PFM_ATTR_NULL
};

int
pfm_intel_snbep_unc_detect(void *this)
{
	int ret;

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

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

	switch(pfm_intel_x86_cfg.model) {
		case 45: /* SandyBridge-EP */
			  break;
		default:
			return PFM_ERR_NOTSUPP;
	}
	return PFM_SUCCESS;
}

int
pfm_intel_ivbep_unc_detect(void *this)
{
       int ret;

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

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

       switch(pfm_intel_x86_cfg.model) {
               case 62: /* SandyBridge-EP */
                         break;
               default:
                       return PFM_ERR_NOTSUPP;
       }
       return PFM_SUCCESS;
}

static void
display_com(void *this, pfmlib_event_desc_t *e, void *val)
{
	const intel_x86_entry_t *pe = this_pe(this);
	pfm_snbep_unc_reg_t *reg = val;

	__pfm_vbprintf("[UNC=0x%"PRIx64" event=0x%x umask=0x%x en=%d "
		       "inv=%d edge=%d thres=%d] %s\n",
			reg->val,
			reg->com.unc_event,
			reg->com.unc_umask,
			reg->com.unc_en,
			reg->com.unc_inv,
			reg->com.unc_edge,
			reg->com.unc_thres,
			pe[e->event].name);
}

static void
display_reg(void *this, pfmlib_event_desc_t *e, pfm_snbep_unc_reg_t reg)
{
	pfmlib_pmu_t *pmu = this;
	if (pmu->display_reg)
		pmu->display_reg(this, e, &reg);
	else
		display_com(this, e, &reg);
}

static inline int
is_occ_event(void *this, int idx)
{
	pfmlib_pmu_t *pmu = this;
	const intel_x86_entry_t *pe = this_pe(this);

	return (pmu->flags & INTEL_PMU_FL_UNC_OCC) && (pe[idx].code & 0x80);
}

static inline int
get_pcu_filt_band(void *this, pfm_snbep_unc_reg_t reg)
{
#define PCU_FREQ_BAND0_CODE	0xb /* event code for UNC_P_FREQ_BAND0_CYCLES */
	return reg.pcu.unc_event - PCU_FREQ_BAND0_CODE;
}

int
snbep_unc_add_defaults(void *this, pfmlib_event_desc_t *e,
			   unsigned int msk,
			   uint64_t *umask,
			   pfm_snbep_unc_reg_t *filters,
			   unsigned int max_grpid)
{
	const intel_x86_entry_t *pe = this_pe(this);
	const intel_x86_entry_t *ent;
	unsigned int i;
	int j, k, added, skip;
	int idx;

	k = e->nattrs;
	ent = pe+e->event;

	for(i=0; msk; msk >>=1, i++) {

		if (!(msk & 0x1))
			continue;

		added = skip = 0;

		for (j = 0; j < e->npattrs; j++) {
			if (e->pattrs[j].ctrl != PFM_ATTR_CTRL_PMU)
				continue;

			if (e->pattrs[j].type != PFM_ATTR_UMASK)
				continue;

			idx = e->pattrs[j].idx;

			if (ent->umasks[idx].grpid != i)
				continue;

			if (max_grpid != INTEL_X86_MAX_GRPID && i > max_grpid) {
				skip = 1;
				continue;
			}

			if (intel_x86_uflag(this, e->event, idx, INTEL_X86_GRP_DFL_NONE)) {
				skip = 1;
				continue;
			}

			/* umask is default for group */
			if (intel_x86_uflag(this, e->event, idx, INTEL_X86_DFL)) {
				DPRINT("added default %s for group %d j=%d idx=%d ucode=0x%"PRIx64"\n",
					ent->umasks[idx].uname,
					i,	
					j,
					idx,
					ent->umasks[idx].ucode);
				/*
				 * default could be an alias, but
				 * ucode must reflect actual code
				 */
				*umask |= ent->umasks[idx].ucode >> 8;

				filters[0].val |= pe[e->event].umasks[idx].ufilters[0];
				filters[1].val |= pe[e->event].umasks[idx].ufilters[1];

				e->attrs[k].id = j; /* pattrs index */
				e->attrs[k].ival = 0;
				k++;

				added++;
				if (intel_x86_eflag(this, e->event, INTEL_X86_GRP_EXCL))
					goto done;

				if (intel_x86_uflag(this, e->event, idx, INTEL_X86_EXCL_GRP_GT)) {
					if (max_grpid != INTEL_X86_MAX_GRPID) {
						DPRINT("two max_grpid, old=%d new=%d\n", max_grpid, ent->umasks[idx].grpid);
						return PFM_ERR_UMASK;
					}
					max_grpid = ent->umasks[idx].grpid;
				}
			}
		}
		if (!added && !skip) {
			DPRINT("no default found for event %s unit mask group %d (max_grpid=%d)\n", ent->name, i, max_grpid);
			return PFM_ERR_UMASK;
		}
	}
	DPRINT("max_grpid=%d nattrs=%d k=%d umask=0x%"PRIx64"\n", max_grpid, e->nattrs, k, *umask);
done:
	e->nattrs = k;
	return PFM_SUCCESS;
}


/*
 * common encoding routine
 */
int
pfm_intel_snbep_unc_get_encoding(void *this, pfmlib_event_desc_t *e)
{
	const intel_x86_entry_t *pe = this_pe(this);
	unsigned int grpmsk, ugrpmsk = 0;
	unsigned int max_grpid = INTEL_X86_MAX_GRPID;
	unsigned int last_grpid =  INTEL_X86_MAX_GRPID;
	int umodmsk = 0, modmsk_r = 0;
	int pcu_filt_band = -1;
	pfm_snbep_unc_reg_t reg;
	pfm_snbep_unc_reg_t filters[INTEL_X86_MAX_FILTERS];
	pfm_snbep_unc_reg_t addr;
	pfm_event_attr_info_t *a;
	uint64_t val, umask1, umask2;
	int k, ret;
	int has_cbo_tid = 0;
	unsigned int grpid;
	int grpcounts[INTEL_X86_NUM_GRP];
	int ncombo[INTEL_X86_NUM_GRP];
	char umask_str[PFMLIB_EVT_MAX_NAME_LEN];

	memset(grpcounts, 0, sizeof(grpcounts));
	memset(ncombo, 0, sizeof(ncombo));
	memset(filters, 0, sizeof(filters));

	addr.val = 0;

	pe = this_pe(this);

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

	reg.val = val = pe[e->event].code;

	/* take into account hardcoded umask */
	umask1 = (val >> 8) & 0xff;
	umask2 = umask1;

	grpmsk = (1 << pe[e->event].ngrp)-1;

	modmsk_r = pe[e->event].modmsk_req;

	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) {
			uint64_t um;

			grpid = pe[e->event].umasks[a->idx].grpid;

			/*
			 * certain event groups are meant to be
			 * exclusive, i.e., only unit masks of one group
			 * can be used
			 */
			if (last_grpid != INTEL_X86_MAX_GRPID && grpid != last_grpid
			    && intel_x86_eflag(this, e->event, INTEL_X86_GRP_EXCL)) {
				DPRINT("exclusive unit mask group error\n");
				return PFM_ERR_FEATCOMB;
			}

			/*
			 * selecting certain umasks in a group may exclude any umasks
			 * from any groups with a higher index
			 *
			 * enforcement requires looking at the grpid of all the umasks
			 */
			if (intel_x86_uflag(this, e->event, a->idx, INTEL_X86_EXCL_GRP_GT))
				max_grpid = grpid;

			/*
			 * certain event groups are meant to be
			 * exclusive, i.e., only unit masks of one group
			 * can be used
			 */
			if (last_grpid != INTEL_X86_MAX_GRPID && grpid != last_grpid
			    && intel_x86_eflag(this, e->event, INTEL_X86_GRP_EXCL)) {
				DPRINT("exclusive unit mask group error\n");
				return PFM_ERR_FEATCOMB;
			}
			/*
			 * upper layer has removed duplicates
			 * so if we come here more than once, it is for two
			 * disinct umasks
			 *
			 * NCOMBO=no combination of unit masks within the same
			 * umask group
			 */
			++grpcounts[grpid];

			/* mark that we have a umask with NCOMBO in this group */
			if (intel_x86_uflag(this, e->event, a->idx, INTEL_X86_NCOMBO))
				ncombo[grpid] = 1;

			/*
			 * if more than one umask in this group but one is marked
			 * with ncombo, then fail. It is okay to combine umask within
			 * a group as long as none is tagged with NCOMBO
			 */
			if (grpcounts[grpid] > 1 && ncombo[grpid])  {
				DPRINT("umask %s does not support unit mask combination within group %d\n", pe[e->event].umasks[a->idx].uname, grpid);
				return PFM_ERR_FEATCOMB;
			}

			last_grpid = grpid;

			um = pe[e->event].umasks[a->idx].ucode;
			filters[0].val |= pe[e->event].umasks[a->idx].ufilters[0];
			filters[1].val |= pe[e->event].umasks[a->idx].ufilters[1];

			um >>= 8;
			umask2  |= um;

			ugrpmsk |= 1 << pe[e->event].umasks[a->idx].grpid;

			/* PCU occ event */
			if (is_occ_event(this, e->event)) {
				reg.pcu.unc_occ = umask2 >> 6;
				umask2 = 0;
			} else
				reg.val |= umask2 << 8;

			evt_strcat(umask_str, ":%s", pe[e->event].umasks[a->idx].uname);

			modmsk_r |= pe[e->event].umasks[a->idx].umodmsk_req;

		} else if (a->type == PFM_ATTR_RAW_UMASK) {

			/* there can only be one RAW_UMASK per event */

			/* sanity check */
			if (a->idx & ~0xff) {
				DPRINT("raw umask is 8-bit wide\n");
				return PFM_ERR_ATTR;
			}
			/* override umask */
			umask2 = a->idx & 0xff;
			ugrpmsk = grpmsk;
		} else {
			uint64_t ival = e->attrs[k].ival;
			switch(a->idx) {
				case SNBEP_UNC_ATTR_I: /* invert */
					if (is_occ_event(this, e->event))
						reg.pcu.unc_occ_inv = !!ival;
					else
						reg.com.unc_inv = !!ival;
					umodmsk |= _SNBEP_UNC_ATTR_I;
					break;
				case SNBEP_UNC_ATTR_E: /* edge */
					if (is_occ_event(this, e->event))
						reg.pcu.unc_occ_edge = !!ival;
					else
						reg.com.unc_edge = !!ival;
					umodmsk |= _SNBEP_UNC_ATTR_E;
					break;
				case SNBEP_UNC_ATTR_T8: /* counter-mask */
					/* already forced, cannot overwrite */
					if (ival > 255)
						return PFM_ERR_ATTR_VAL;
					reg.com.unc_thres = ival;
					umodmsk |= _SNBEP_UNC_ATTR_T8;
					break;
				case SNBEP_UNC_ATTR_T5: /* pcu counter-mask */
					/* already forced, cannot overwrite */
					if (ival > 31)
						return PFM_ERR_ATTR_VAL;
					reg.pcu.unc_thres = ival;
					umodmsk |= _SNBEP_UNC_ATTR_T5;
					break;
				case SNBEP_UNC_ATTR_TF: /* thread id */
					if (ival > 1) {
						DPRINT("invalid thread id, must be < 1");
						return PFM_ERR_ATTR_VAL;
					}
					reg.cbo.unc_tid = 1;
					has_cbo_tid = 1;
					filters[0].cbo_filt.tid = ival;
					umodmsk |= _SNBEP_UNC_ATTR_TF;
					break;
				case SNBEP_UNC_ATTR_CF: /* core id */
					if (ival > 15)
						return PFM_ERR_ATTR_VAL;
					reg.cbo.unc_tid = 1;
					filters[0].cbo_filt.cid = ival;
					has_cbo_tid = 1;
					umodmsk |= _SNBEP_UNC_ATTR_CF;
					break;
				case SNBEP_UNC_ATTR_NF: /* node id filter0 */
					if (ival > 255 || ival == 0) {
						DPRINT("invalid nf,  0 < nf < 256\n");
						return PFM_ERR_ATTR_VAL;
					}
					filters[0].cbo_filt.nid = ival;
					umodmsk |= _SNBEP_UNC_ATTR_NF;
					break;
				case SNBEP_UNC_ATTR_NF1: /* node id filter1 */
					if (ival > 255 || ival == 0) {
						DPRINT("invalid nf,  0 < nf < 256\n");
						return PFM_ERR_ATTR_VAL;
					}
					filters[1].ivbep_cbo_filt1.nid = ival;
					umodmsk |= _SNBEP_UNC_ATTR_NF1;
					break;
				case SNBEP_UNC_ATTR_FF: /* freq band filter */
					if (ival > 255)
						return PFM_ERR_ATTR_VAL;
					pcu_filt_band = get_pcu_filt_band(this, reg);
					filters[0].val = ival << (pcu_filt_band * 8);
					umodmsk |= _SNBEP_UNC_ATTR_FF;
					break;
				case SNBEP_UNC_ATTR_A: /* addr filter */
					if (ival & ~((1ULL << 40)-1)) {
						DPRINT("address filter 40bits max\n");
						return PFM_ERR_ATTR_VAL;
					}
					addr.ha_addr.lo_addr = ival; /* LSB 26 bits */
					addr.ha_addr.hi_addr = (ival >> 26) & ((1ULL << 14)-1);
					umodmsk |= _SNBEP_UNC_ATTR_A;
					break;
				case SNBEP_UNC_ATTR_ISOC: /* isoc filter */
					filters[1].ivbep_cbo_filt1.isoc = !!ival;
					break;
				case SNBEP_UNC_ATTR_NC: /* nc filter */
					filters[1].ivbep_cbo_filt1.nc = !!ival;
					break;
			}
		}
	}
	/*
	 * check that there is at least of unit mask in each unit mask group
	 */
	if (pe[e->event].numasks && (ugrpmsk != grpmsk || ugrpmsk == 0)) {
		uint64_t um = 0;
		ugrpmsk ^= grpmsk;
		ret = snbep_unc_add_defaults(this, e, ugrpmsk, &um, filters, max_grpid);
		if (ret != PFM_SUCCESS)
			return ret;
		umask2 |= um;
	}

	/*
	 * nf= is only required on some events in CBO
	 */
	if (!(modmsk_r & _SNBEP_UNC_ATTR_NF) && (umodmsk & _SNBEP_UNC_ATTR_NF)) {
		DPRINT("using nf= on an umask which does not require it\n");
		return PFM_ERR_ATTR;
	}
	if (!(modmsk_r & _SNBEP_UNC_ATTR_NF1) && (umodmsk & _SNBEP_UNC_ATTR_NF1)) {
		DPRINT("using nf= on an umask which does not require it\n");
		return PFM_ERR_ATTR;
	}

	if (modmsk_r && !(umodmsk & modmsk_r)) {
		DPRINT("required modifiers missing: 0x%x\n", modmsk_r);
		return PFM_ERR_ATTR;
	}

	evt_strcat(e->fstr, "%s", pe[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)
			evt_strcat(e->fstr, ":%s", pe[e->event].umasks[a->idx].uname);
		else if (a->type == PFM_ATTR_RAW_UMASK)
			evt_strcat(e->fstr, ":0x%x", a->idx);
	}
	DPRINT("umask2=0x%"PRIx64" umask1=0x%"PRIx64"\n", umask2, umask1);
	e->count = 0;
	reg.val |= (umask1 | umask2)  << 8;

	e->codes[e->count++] = reg.val;

	/*
	 * handles C-box filter
	 */
	if (filters[0].val || filters[1].val || has_cbo_tid)
		e->codes[e->count++] = filters[0].val;
	if (filters[1].val)
		e->codes[e->count++] = filters[1].val;

	/* HA address matcher */
	if (addr.val)
		e->codes[e->count++] = addr.val;

	for (k = 0; k < e->npattrs; k++) {
		int idx;

		if (e->pattrs[k].ctrl != PFM_ATTR_CTRL_PMU)
			continue;

		if (e->pattrs[k].type == PFM_ATTR_UMASK)
			continue;

		idx = e->pattrs[k].idx;
		switch(idx) {
		case SNBEP_UNC_ATTR_E:
			if (is_occ_event(this, e->event))
				evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, reg.pcu.unc_occ_edge);
			else
				evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, reg.com.unc_edge);
			break;
		case SNBEP_UNC_ATTR_I:
			if (is_occ_event(this, e->event))
				evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, reg.pcu.unc_occ_inv);
			else
				evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, reg.com.unc_inv);
			break;
		case SNBEP_UNC_ATTR_T8:
			evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, reg.com.unc_thres);
			break;
		case SNBEP_UNC_ATTR_T5:
			evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, reg.pcu.unc_thres);
			break;
		case SNBEP_UNC_ATTR_TF:
			evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, reg.cbo.unc_tid);
			break;
		case SNBEP_UNC_ATTR_CF:
			evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, filters[0].cbo_filt.cid);
			break;
		case SNBEP_UNC_ATTR_FF:
			evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, (filters[0].val >> (pcu_filt_band*8)) & 0xff);
			break;
		case SNBEP_UNC_ATTR_ISOC:
			evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, filters[1].ivbep_cbo_filt1.isoc);
			break;
		case SNBEP_UNC_ATTR_NC:
			evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, filters[1].ivbep_cbo_filt1.nc);
			break;
		case SNBEP_UNC_ATTR_NF:
			if (modmsk_r & _SNBEP_UNC_ATTR_NF)
				evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, filters[0].cbo_filt.nid);
			break;
		case SNBEP_UNC_ATTR_NF1:
			if (modmsk_r & _SNBEP_UNC_ATTR_NF1)
				evt_strcat(e->fstr, ":%s=%lu", snbep_unc_mods[idx].name, filters[1].ivbep_cbo_filt1.nid);
			break;
		case SNBEP_UNC_ATTR_A:
			evt_strcat(e->fstr, ":%s=0x%lx", snbep_unc_mods[idx].name,
				   addr.ha_addr.hi_addr << 26 | addr.ha_addr.lo_addr);
			break;
		}
	}
	display_reg(this, e, reg);
	return PFM_SUCCESS;
}

int
pfm_intel_snbep_unc_can_auto_encode(void *this, int pidx, int uidx)
{
	if (intel_x86_eflag(this, pidx, INTEL_X86_NO_AUTOENCODE))
		return 0;

	return !intel_x86_uflag(this, pidx, uidx, INTEL_X86_NO_AUTOENCODE);
}

int
pfm_intel_snbep_unc_get_event_attr_info(void *this, int pidx, int attr_idx, pfm_event_attr_info_t *info)
{
	const intel_x86_entry_t *pe = this_pe(this);
	const pfmlib_attr_desc_t *atdesc = this_atdesc(this);
	int numasks, idx;

	numasks = intel_x86_num_umasks(this, pidx);
	if (attr_idx < numasks) {
		idx = intel_x86_attr2umask(this, pidx, attr_idx);
		info->name = pe[pidx].umasks[idx].uname;
		info->desc = pe[pidx].umasks[idx].udesc;
		info->equiv= pe[pidx].umasks[idx].uequiv;

		info->code = pe[pidx].umasks[idx].ucode;

		if (!intel_x86_uflag(this, pidx, idx, INTEL_X86_CODE_OVERRIDE))
			info->code >>= 8;

		if (info->code == 0)
			info->code = pe[pidx].umasks[idx].ufilters[0];

		info->type = PFM_ATTR_UMASK;
		info->is_dfl = intel_x86_uflag(this, pidx, idx, INTEL_X86_DFL);
		info->is_precise = intel_x86_uflag(this, pidx, idx, INTEL_X86_PEBS);
	} else {
		idx = intel_x86_attr2mod(this, pidx, attr_idx);
		info->name = atdesc[idx].name;
		info->desc = atdesc[idx].desc;
		info->type = atdesc[idx].type;
		info->equiv= NULL;
		info->code = idx;
		info->is_dfl = 0;
		info->is_precise = 0;
	}

	info->ctrl = PFM_ATTR_CTRL_PMU;
	info->idx = idx; /* namespace specific index */
	info->dfl_val64 = 0;

	return PFM_SUCCESS;
}
