// SPDX-License-Identifier: GPL-2.0
/*
 * Support for libpfm4 event encoding.
 *
 * Copyright 2020 Google LLC.
 */
#include "util/cpumap.h"
#include "util/debug.h"
#include "util/event.h"
#include "util/evlist.h"
#include "util/evsel.h"
#include "util/parse-events.h"
#include "util/pmus.h"
#include "util/pfm.h"
#include "util/strbuf.h"
#include "util/thread_map.h"

#include <string.h>
#include <linux/kernel.h>
#include <perfmon/pfmlib_perf_event.h>

static void libpfm_initialize(void)
{
	int ret;

	ret = pfm_initialize();
	if (ret != PFM_SUCCESS) {
		ui__warning("libpfm failed to initialize: %s\n",
			pfm_strerror(ret));
	}
}

int parse_libpfm_events_option(const struct option *opt, const char *str,
			int unset __maybe_unused)
{
	struct evlist *evlist = *(struct evlist **)opt->value;
	struct perf_event_attr attr;
	struct perf_pmu *pmu;
	struct evsel *evsel, *grp_leader = NULL;
	char *p, *q, *p_orig;
	const char *sep;
	int grp_evt = -1;
	int ret;

	libpfm_initialize();

	p_orig = p = strdup(str);
	if (!p)
		return -1;
	/*
	 * force loading of the PMU list
	 */
	perf_pmus__scan(NULL);

	for (q = p; strsep(&p, ",{}"); q = p) {
		sep = p ? str + (p - p_orig - 1) : "";
		if (*sep == '{') {
			if (grp_evt > -1) {
				ui__error(
					"nested event groups not supported\n");
				goto error;
			}
			grp_evt++;
		}

		/* no event */
		if (*q == '\0') {
			if (*sep == '}') {
				if (grp_evt < 0) {
					ui__error("cannot close a non-existing event group\n");
					goto error;
				}
				grp_evt--;
			}
			continue;
		}

		memset(&attr, 0, sizeof(attr));
		event_attr_init(&attr);

		ret = pfm_get_perf_event_encoding(q, PFM_PLM0|PFM_PLM3,
						&attr, NULL, NULL);

		if (ret != PFM_SUCCESS) {
			ui__error("failed to parse event %s : %s\n", str,
				  pfm_strerror(ret));
			goto error;
		}

		pmu = perf_pmus__find_by_type((unsigned int)attr.type);
		evsel = parse_events__add_event(evlist->core.nr_entries,
						&attr, q, /*metric_id=*/NULL,
						pmu);
		if (evsel == NULL)
			goto error;

		evsel->is_libpfm_event = true;

		evlist__add(evlist, evsel);

		if (grp_evt == 0)
			grp_leader = evsel;

		if (grp_evt > -1) {
			evsel__set_leader(evsel, grp_leader);
			grp_leader->core.nr_members++;
			grp_evt++;
		}

		if (*sep == '}') {
			if (grp_evt < 0) {
				ui__error(
				   "cannot close a non-existing event group\n");
				goto error;
			}
			grp_leader = NULL;
			grp_evt = -1;
		}
	}
	free(p_orig);
	return 0;
error:
	free(p_orig);
	return -1;
}

static bool is_libpfm_event_supported(const char *name, struct perf_cpu_map *cpus,
				      struct perf_thread_map *threads)
{
	struct perf_pmu *pmu;
	struct evsel *evsel;
	struct perf_event_attr attr = {};
	bool result = true;
	int ret;

	ret = pfm_get_perf_event_encoding(name, PFM_PLM0|PFM_PLM3,
					  &attr, NULL, NULL);
	if (ret != PFM_SUCCESS)
		return false;

	pmu = perf_pmus__find_by_type((unsigned int)attr.type);
	evsel = parse_events__add_event(0, &attr, name, /*metric_id=*/NULL, pmu);
	if (evsel == NULL)
		return false;

	evsel->is_libpfm_event = true;

	if (evsel__open(evsel, cpus, threads) < 0)
		result = false;

	evsel__close(evsel);
	evsel__delete(evsel);

	return result;
}

static const char *srcs[PFM_ATTR_CTRL_MAX] = {
	[PFM_ATTR_CTRL_UNKNOWN] = "???",
	[PFM_ATTR_CTRL_PMU] = "PMU",
	[PFM_ATTR_CTRL_PERF_EVENT] = "perf_event",
};

static void
print_attr_flags(struct strbuf *buf, const pfm_event_attr_info_t *info)
{
	if (info->is_dfl)
		strbuf_addf(buf, "[default] ");

	if (info->is_precise)
		strbuf_addf(buf, "[precise] ");
}

static void
print_libpfm_event(const struct print_callbacks *print_cb, void *print_state,
		const pfm_pmu_info_t *pinfo, const pfm_event_info_t *info,
		struct strbuf *buf)
{
	int j, ret;
	char topic[80], name[80];
	struct perf_cpu_map *cpus = perf_cpu_map__empty_new(1);
	struct perf_thread_map *threads = thread_map__new_by_tid(0);

	strbuf_setlen(buf, 0);
	snprintf(topic, sizeof(topic), "pfm %s", pinfo->name);

	snprintf(name, sizeof(name), "%s::%s", pinfo->name, info->name);
	strbuf_addf(buf, "Code: 0x%"PRIx64"\n", info->code);

	pfm_for_each_event_attr(j, info) {
		pfm_event_attr_info_t ainfo;
		const char *src;

		ainfo.size = sizeof(ainfo);
		ret = pfm_get_event_attr_info(info->idx, j, PFM_OS_PERF_EVENT_EXT, &ainfo);
		if (ret != PFM_SUCCESS)
			continue;

		if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX)
			ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN;

		src = srcs[ainfo.ctrl];
		switch (ainfo.type) {
		case PFM_ATTR_UMASK: /* Ignore for now */
			break;
		case PFM_ATTR_MOD_BOOL:
			strbuf_addf(buf, " Modif: %s: [%s] : %s (boolean)\n", src,
				    ainfo.name, ainfo.desc);
			break;
		case PFM_ATTR_MOD_INTEGER:
			strbuf_addf(buf, " Modif: %s: [%s] : %s (integer)\n", src,
				    ainfo.name, ainfo.desc);
			break;
		case PFM_ATTR_NONE:
		case PFM_ATTR_RAW_UMASK:
		case PFM_ATTR_MAX:
		default:
			strbuf_addf(buf, " Attr: %s: [%s] : %s\n", src,
				    ainfo.name, ainfo.desc);
		}
	}

	if (is_libpfm_event_supported(name, cpus, threads)) {
		print_cb->print_event(print_state, pinfo->name, topic,
				      name, info->equiv,
				      /*scale_unit=*/NULL,
				      /*deprecated=*/NULL, "PFM event",
				      info->desc, /*long_desc=*/NULL,
				      /*encoding_desc=*/buf->buf);
	}

	pfm_for_each_event_attr(j, info) {
		pfm_event_attr_info_t ainfo;
		const char *src;

		strbuf_setlen(buf, 0);

		ainfo.size = sizeof(ainfo);
		ret = pfm_get_event_attr_info(info->idx, j, PFM_OS_PERF_EVENT_EXT, &ainfo);
		if (ret != PFM_SUCCESS)
			continue;

		if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX)
			ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN;

		src = srcs[ainfo.ctrl];
		if (ainfo.type == PFM_ATTR_UMASK) {
			strbuf_addf(buf, "Umask: 0x%02"PRIx64" : %s: ",
				ainfo.code, src);
			print_attr_flags(buf, &ainfo);
			snprintf(name, sizeof(name), "%s::%s:%s",
				 pinfo->name, info->name, ainfo.name);

			if (!is_libpfm_event_supported(name, cpus, threads))
				continue;

			print_cb->print_event(print_state,
					pinfo->name,
					topic,
					name, /*alias=*/NULL,
					/*scale_unit=*/NULL,
					/*deprecated=*/NULL, "PFM event",
					ainfo.desc, /*long_desc=*/NULL,
					/*encoding_desc=*/buf->buf);
		}
	}

	perf_cpu_map__put(cpus);
	perf_thread_map__put(threads);
}

void print_libpfm_events(const struct print_callbacks *print_cb, void *print_state)
{
	pfm_event_info_t info;
	pfm_pmu_info_t pinfo;
	int p, ret;
	struct strbuf storage;

	libpfm_initialize();

	/* initialize to zero to indicate ABI version */
	info.size  = sizeof(info);
	pinfo.size = sizeof(pinfo);

	strbuf_init(&storage, 2048);

	pfm_for_all_pmus(p) {
		ret = pfm_get_pmu_info(p, &pinfo);
		if (ret != PFM_SUCCESS)
			continue;

		/* only print events that are supported by host HW */
		if (!pinfo.is_present)
			continue;

		/* handled by perf directly */
		if (pinfo.pmu == PFM_PMU_PERF_EVENT)
			continue;

		for (int i = pinfo.first_event; i != -1; i = pfm_get_event_next(i)) {
			ret = pfm_get_event_info(i, PFM_OS_PERF_EVENT_EXT,
						&info);
			if (ret != PFM_SUCCESS)
				continue;

			print_libpfm_event(print_cb, print_state, &pinfo, &info, &storage);
		}
	}
	strbuf_release(&storage);
}
