/*
 * Copyright (C) 2013 Advanced Micro Devices, Inc.
 *
 * Author: Steven Kinney <Steven.Kinney@amd.com>
 * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
 *
 * Perf: amd_iommu - AMD IOMMU Performance Counter PMU implementation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/perf_event.h>
#include <linux/module.h>
#include <linux/cpumask.h>
#include <linux/slab.h>

#include "perf_event.h"
#include "perf_event_amd_iommu.h"

#define COUNTER_SHIFT		16

#define _GET_BANK(ev)       ((u8)(ev->hw.extra_reg.reg >> 8))
#define _GET_CNTR(ev)       ((u8)(ev->hw.extra_reg.reg))

/* iommu pmu config masks */
#define _GET_CSOURCE(ev)    ((ev->hw.config & 0xFFULL))
#define _GET_DEVID(ev)      ((ev->hw.config >> 8)  & 0xFFFFULL)
#define _GET_PASID(ev)      ((ev->hw.config >> 24) & 0xFFFFULL)
#define _GET_DOMID(ev)      ((ev->hw.config >> 40) & 0xFFFFULL)
#define _GET_DEVID_MASK(ev) ((ev->hw.extra_reg.config)  & 0xFFFFULL)
#define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xFFFFULL)
#define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xFFFFULL)

static struct perf_amd_iommu __perf_iommu;

struct perf_amd_iommu {
	struct pmu pmu;
	u8 max_banks;
	u8 max_counters;
	u64 cntr_assign_mask;
	raw_spinlock_t lock;
	const struct attribute_group *attr_groups[4];
};

#define format_group	attr_groups[0]
#define cpumask_group	attr_groups[1]
#define events_group	attr_groups[2]
#define null_group	attr_groups[3]

/*---------------------------------------------
 * sysfs format attributes
 *---------------------------------------------*/
PMU_FORMAT_ATTR(csource,    "config:0-7");
PMU_FORMAT_ATTR(devid,      "config:8-23");
PMU_FORMAT_ATTR(pasid,      "config:24-39");
PMU_FORMAT_ATTR(domid,      "config:40-55");
PMU_FORMAT_ATTR(devid_mask, "config1:0-15");
PMU_FORMAT_ATTR(pasid_mask, "config1:16-31");
PMU_FORMAT_ATTR(domid_mask, "config1:32-47");

static struct attribute *iommu_format_attrs[] = {
	&format_attr_csource.attr,
	&format_attr_devid.attr,
	&format_attr_pasid.attr,
	&format_attr_domid.attr,
	&format_attr_devid_mask.attr,
	&format_attr_pasid_mask.attr,
	&format_attr_domid_mask.attr,
	NULL,
};

static struct attribute_group amd_iommu_format_group = {
	.name = "format",
	.attrs = iommu_format_attrs,
};

/*---------------------------------------------
 * sysfs events attributes
 *---------------------------------------------*/
struct amd_iommu_event_desc {
	struct kobj_attribute attr;
	const char *event;
};

static ssize_t _iommu_event_show(struct kobject *kobj,
				struct kobj_attribute *attr, char *buf)
{
	struct amd_iommu_event_desc *event =
		container_of(attr, struct amd_iommu_event_desc, attr);
	return sprintf(buf, "%s\n", event->event);
}

#define AMD_IOMMU_EVENT_DESC(_name, _event)			\
{								\
	.attr  = __ATTR(_name, 0444, _iommu_event_show, NULL),	\
	.event = _event,					\
}

static struct amd_iommu_event_desc amd_iommu_v2_event_descs[] = {
	AMD_IOMMU_EVENT_DESC(mem_pass_untrans,        "csource=0x01"),
	AMD_IOMMU_EVENT_DESC(mem_pass_pretrans,       "csource=0x02"),
	AMD_IOMMU_EVENT_DESC(mem_pass_excl,           "csource=0x03"),
	AMD_IOMMU_EVENT_DESC(mem_target_abort,        "csource=0x04"),
	AMD_IOMMU_EVENT_DESC(mem_trans_total,         "csource=0x05"),
	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_hit,   "csource=0x06"),
	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_mis,   "csource=0x07"),
	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_hit,   "csource=0x08"),
	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_mis,   "csource=0x09"),
	AMD_IOMMU_EVENT_DESC(mem_dte_hit,             "csource=0x0a"),
	AMD_IOMMU_EVENT_DESC(mem_dte_mis,             "csource=0x0b"),
	AMD_IOMMU_EVENT_DESC(page_tbl_read_tot,       "csource=0x0c"),
	AMD_IOMMU_EVENT_DESC(page_tbl_read_nst,       "csource=0x0d"),
	AMD_IOMMU_EVENT_DESC(page_tbl_read_gst,       "csource=0x0e"),
	AMD_IOMMU_EVENT_DESC(int_dte_hit,             "csource=0x0f"),
	AMD_IOMMU_EVENT_DESC(int_dte_mis,             "csource=0x10"),
	AMD_IOMMU_EVENT_DESC(cmd_processed,           "csource=0x11"),
	AMD_IOMMU_EVENT_DESC(cmd_processed_inv,       "csource=0x12"),
	AMD_IOMMU_EVENT_DESC(tlb_inv,                 "csource=0x13"),
	{ /* end: all zeroes */ },
};

/*---------------------------------------------
 * sysfs cpumask attributes
 *---------------------------------------------*/
static cpumask_t iommu_cpumask;

static ssize_t _iommu_cpumask_show(struct device *dev,
				   struct device_attribute *attr,
				   char *buf)
{
	return cpumap_print_to_pagebuf(true, buf, &iommu_cpumask);
}
static DEVICE_ATTR(cpumask, S_IRUGO, _iommu_cpumask_show, NULL);

static struct attribute *iommu_cpumask_attrs[] = {
	&dev_attr_cpumask.attr,
	NULL,
};

static struct attribute_group amd_iommu_cpumask_group = {
	.attrs = iommu_cpumask_attrs,
};

/*---------------------------------------------*/

static int get_next_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu)
{
	unsigned long flags;
	int shift, bank, cntr, retval;
	int max_banks = perf_iommu->max_banks;
	int max_cntrs = perf_iommu->max_counters;

	raw_spin_lock_irqsave(&perf_iommu->lock, flags);

	for (bank = 0, shift = 0; bank < max_banks; bank++) {
		for (cntr = 0; cntr < max_cntrs; cntr++) {
			shift = bank + (bank*3) + cntr;
			if (perf_iommu->cntr_assign_mask & (1ULL<<shift)) {
				continue;
			} else {
				perf_iommu->cntr_assign_mask |= (1ULL<<shift);
				retval = ((u16)((u16)bank<<8) | (u8)(cntr));
				goto out;
			}
		}
	}
	retval = -ENOSPC;
out:
	raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
	return retval;
}

static int clear_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu,
					u8 bank, u8 cntr)
{
	unsigned long flags;
	int max_banks, max_cntrs;
	int shift = 0;

	max_banks = perf_iommu->max_banks;
	max_cntrs = perf_iommu->max_counters;

	if ((bank > max_banks) || (cntr > max_cntrs))
		return -EINVAL;

	shift = bank + cntr + (bank*3);

	raw_spin_lock_irqsave(&perf_iommu->lock, flags);
	perf_iommu->cntr_assign_mask &= ~(1ULL<<shift);
	raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);

	return 0;
}

static int perf_iommu_event_init(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	struct perf_amd_iommu *perf_iommu;
	u64 config, config1;

	/* test the event attr type check for PMU enumeration */
	if (event->attr.type != event->pmu->type)
		return -ENOENT;

	/*
	 * IOMMU counters are shared across all cores.
	 * Therefore, it does not support per-process mode.
	 * Also, it does not support event sampling mode.
	 */
	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
		return -EINVAL;

	/* IOMMU counters do not have usr/os/guest/host bits */
	if (event->attr.exclude_user || event->attr.exclude_kernel ||
	    event->attr.exclude_host || event->attr.exclude_guest)
		return -EINVAL;

	if (event->cpu < 0)
		return -EINVAL;

	perf_iommu = &__perf_iommu;

	if (event->pmu != &perf_iommu->pmu)
		return -ENOENT;

	if (perf_iommu) {
		config = event->attr.config;
		config1 = event->attr.config1;
	} else {
		return -EINVAL;
	}

	/* integrate with iommu base devid (0000), assume one iommu */
	perf_iommu->max_banks =
		amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID);
	perf_iommu->max_counters =
		amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID);
	if ((perf_iommu->max_banks == 0) || (perf_iommu->max_counters == 0))
		return -EINVAL;

	/* update the hw_perf_event struct with the iommu config data */
	hwc->config = config;
	hwc->extra_reg.config = config1;

	return 0;
}

static void perf_iommu_enable_event(struct perf_event *ev)
{
	u8 csource = _GET_CSOURCE(ev);
	u16 devid = _GET_DEVID(ev);
	u64 reg = 0ULL;

	reg = csource;
	amd_iommu_pc_get_set_reg_val(devid,
			_GET_BANK(ev), _GET_CNTR(ev) ,
			 IOMMU_PC_COUNTER_SRC_REG, &reg, true);

	reg = 0ULL | devid | (_GET_DEVID_MASK(ev) << 32);
	if (reg)
		reg |= (1UL << 31);
	amd_iommu_pc_get_set_reg_val(devid,
			_GET_BANK(ev), _GET_CNTR(ev) ,
			 IOMMU_PC_DEVID_MATCH_REG, &reg, true);

	reg = 0ULL | _GET_PASID(ev) | (_GET_PASID_MASK(ev) << 32);
	if (reg)
		reg |= (1UL << 31);
	amd_iommu_pc_get_set_reg_val(devid,
			_GET_BANK(ev), _GET_CNTR(ev) ,
			 IOMMU_PC_PASID_MATCH_REG, &reg, true);

	reg = 0ULL | _GET_DOMID(ev) | (_GET_DOMID_MASK(ev) << 32);
	if (reg)
		reg |= (1UL << 31);
	amd_iommu_pc_get_set_reg_val(devid,
			_GET_BANK(ev), _GET_CNTR(ev) ,
			 IOMMU_PC_DOMID_MATCH_REG, &reg, true);
}

static void perf_iommu_disable_event(struct perf_event *event)
{
	u64 reg = 0ULL;

	amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
			_GET_BANK(event), _GET_CNTR(event),
			IOMMU_PC_COUNTER_SRC_REG, &reg, true);
}

static void perf_iommu_start(struct perf_event *event, int flags)
{
	struct hw_perf_event *hwc = &event->hw;

	pr_debug("perf: amd_iommu:perf_iommu_start\n");
	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
		return;

	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
	hwc->state = 0;

	if (flags & PERF_EF_RELOAD) {
		u64 prev_raw_count =  local64_read(&hwc->prev_count);
		amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
				_GET_BANK(event), _GET_CNTR(event),
				IOMMU_PC_COUNTER_REG, &prev_raw_count, true);
	}

	perf_iommu_enable_event(event);
	perf_event_update_userpage(event);

}

static void perf_iommu_read(struct perf_event *event)
{
	u64 count = 0ULL;
	u64 prev_raw_count = 0ULL;
	u64 delta = 0ULL;
	struct hw_perf_event *hwc = &event->hw;
	pr_debug("perf: amd_iommu:perf_iommu_read\n");

	amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
				_GET_BANK(event), _GET_CNTR(event),
				IOMMU_PC_COUNTER_REG, &count, false);

	/* IOMMU pc counter register is only 48 bits */
	count &= 0xFFFFFFFFFFFFULL;

	prev_raw_count =  local64_read(&hwc->prev_count);
	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
					count) != prev_raw_count)
		return;

	/* Handling 48-bit counter overflowing */
	delta = (count << COUNTER_SHIFT) - (prev_raw_count << COUNTER_SHIFT);
	delta >>= COUNTER_SHIFT;
	local64_add(delta, &event->count);

}

static void perf_iommu_stop(struct perf_event *event, int flags)
{
	struct hw_perf_event *hwc = &event->hw;
	u64 config;

	pr_debug("perf: amd_iommu:perf_iommu_stop\n");

	if (hwc->state & PERF_HES_UPTODATE)
		return;

	perf_iommu_disable_event(event);
	WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
	hwc->state |= PERF_HES_STOPPED;

	if (hwc->state & PERF_HES_UPTODATE)
		return;

	config = hwc->config;
	perf_iommu_read(event);
	hwc->state |= PERF_HES_UPTODATE;
}

static int perf_iommu_add(struct perf_event *event, int flags)
{
	int retval;
	struct perf_amd_iommu *perf_iommu =
			container_of(event->pmu, struct perf_amd_iommu, pmu);

	pr_debug("perf: amd_iommu:perf_iommu_add\n");
	event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;

	/* request an iommu bank/counter */
	retval = get_next_avail_iommu_bnk_cntr(perf_iommu);
	if (retval != -ENOSPC)
		event->hw.extra_reg.reg = (u16)retval;
	else
		return retval;

	if (flags & PERF_EF_START)
		perf_iommu_start(event, PERF_EF_RELOAD);

	return 0;
}

static void perf_iommu_del(struct perf_event *event, int flags)
{
	struct perf_amd_iommu *perf_iommu =
			container_of(event->pmu, struct perf_amd_iommu, pmu);

	pr_debug("perf: amd_iommu:perf_iommu_del\n");
	perf_iommu_stop(event, PERF_EF_UPDATE);

	/* clear the assigned iommu bank/counter */
	clear_avail_iommu_bnk_cntr(perf_iommu,
				     _GET_BANK(event),
				     _GET_CNTR(event));

	perf_event_update_userpage(event);
}

static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu)
{
	struct attribute **attrs;
	struct attribute_group *attr_group;
	int i = 0, j;

	while (amd_iommu_v2_event_descs[i].attr.attr.name)
		i++;

	attr_group = kzalloc(sizeof(struct attribute *)
		* (i + 1) + sizeof(*attr_group), GFP_KERNEL);
	if (!attr_group)
		return -ENOMEM;

	attrs = (struct attribute **)(attr_group + 1);
	for (j = 0; j < i; j++)
		attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr;

	attr_group->name = "events";
	attr_group->attrs = attrs;
	perf_iommu->events_group = attr_group;

	return 0;
}

static __init void amd_iommu_pc_exit(void)
{
	if (__perf_iommu.events_group != NULL) {
		kfree(__perf_iommu.events_group);
		__perf_iommu.events_group = NULL;
	}
}

static __init int _init_perf_amd_iommu(
	struct perf_amd_iommu *perf_iommu, char *name)
{
	int ret;

	raw_spin_lock_init(&perf_iommu->lock);

	/* Init format attributes */
	perf_iommu->format_group = &amd_iommu_format_group;

	/* Init cpumask attributes to only core 0 */
	cpumask_set_cpu(0, &iommu_cpumask);
	perf_iommu->cpumask_group = &amd_iommu_cpumask_group;

	/* Init events attributes */
	if (_init_events_attrs(perf_iommu) != 0)
		pr_err("perf: amd_iommu: Only support raw events.\n");

	/* Init null attributes */
	perf_iommu->null_group = NULL;
	perf_iommu->pmu.attr_groups = perf_iommu->attr_groups;

	ret = perf_pmu_register(&perf_iommu->pmu, name, -1);
	if (ret) {
		pr_err("perf: amd_iommu: Failed to initialized.\n");
		amd_iommu_pc_exit();
	} else {
		pr_info("perf: amd_iommu: Detected. (%d banks, %d counters/bank)\n",
			amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID),
			amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID));
	}

	return ret;
}

static struct perf_amd_iommu __perf_iommu = {
	.pmu = {
		.event_init	= perf_iommu_event_init,
		.add		= perf_iommu_add,
		.del		= perf_iommu_del,
		.start		= perf_iommu_start,
		.stop		= perf_iommu_stop,
		.read		= perf_iommu_read,
	},
	.max_banks		= 0x00,
	.max_counters		= 0x00,
	.cntr_assign_mask	= 0ULL,
	.format_group		= NULL,
	.cpumask_group		= NULL,
	.events_group		= NULL,
	.null_group		= NULL,
};

static __init int amd_iommu_pc_init(void)
{
	/* Make sure the IOMMU PC resource is available */
	if (!amd_iommu_pc_supported())
		return -ENODEV;

	_init_perf_amd_iommu(&__perf_iommu, "amd_iommu");

	return 0;
}

device_initcall(amd_iommu_pc_init);
