// 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/pmu.h"
#include "util/pfm.h"
#include "util/strbuf.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_pmu__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_pmu__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;
			}
			evlist->core.nr_groups++;
			grp_leader = NULL;
			grp_evt = -1;
		}
	}
	free(p_orig);
	return 0;
error:
	free(p_orig);
	return -1;
}

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];

	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);
		}
	}
	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,
			/*metric_name=*/NULL, /*metric_expr=*/NULL);

	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);
			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,
					/*metric_name=*/NULL, /*metric_expr=*/NULL);
		}
	}
}

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