162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include "api/fs/fs.h"
362306a36Sopenharmony_ci#include "util/evsel.h"
462306a36Sopenharmony_ci#include "util/pmu.h"
562306a36Sopenharmony_ci#include "util/pmus.h"
662306a36Sopenharmony_ci#include "util/topdown.h"
762306a36Sopenharmony_ci#include "topdown.h"
862306a36Sopenharmony_ci#include "evsel.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/* Check whether there is a PMU which supports the perf metrics. */
1162306a36Sopenharmony_cibool topdown_sys_has_perf_metrics(void)
1262306a36Sopenharmony_ci{
1362306a36Sopenharmony_ci	static bool has_perf_metrics;
1462306a36Sopenharmony_ci	static bool cached;
1562306a36Sopenharmony_ci	struct perf_pmu *pmu;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci	if (cached)
1862306a36Sopenharmony_ci		return has_perf_metrics;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci	/*
2162306a36Sopenharmony_ci	 * The perf metrics feature is a core PMU feature.
2262306a36Sopenharmony_ci	 * The PERF_TYPE_RAW type is the type of a core PMU.
2362306a36Sopenharmony_ci	 * The slots event is only available when the core PMU
2462306a36Sopenharmony_ci	 * supports the perf metrics feature.
2562306a36Sopenharmony_ci	 */
2662306a36Sopenharmony_ci	pmu = perf_pmus__find_by_type(PERF_TYPE_RAW);
2762306a36Sopenharmony_ci	if (pmu && perf_pmu__have_event(pmu, "slots"))
2862306a36Sopenharmony_ci		has_perf_metrics = true;
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci	cached = true;
3162306a36Sopenharmony_ci	return has_perf_metrics;
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define TOPDOWN_SLOTS		0x0400
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/*
3762306a36Sopenharmony_ci * Check whether a topdown group supports sample-read.
3862306a36Sopenharmony_ci *
3962306a36Sopenharmony_ci * Only Topdown metric supports sample-read. The slots
4062306a36Sopenharmony_ci * event must be the leader of the topdown group.
4162306a36Sopenharmony_ci */
4262306a36Sopenharmony_cibool arch_topdown_sample_read(struct evsel *leader)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	if (!evsel__sys_has_perf_metrics(leader))
4562306a36Sopenharmony_ci		return false;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	if (leader->core.attr.config == TOPDOWN_SLOTS)
4862306a36Sopenharmony_ci		return true;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	return false;
5162306a36Sopenharmony_ci}
52