162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * auxtrace.c: AUX area tracing support
462306a36Sopenharmony_ci * Copyright (c) 2013-2014, Intel Corporation.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <errno.h>
862306a36Sopenharmony_ci#include <stdbool.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "../../../util/header.h"
1162306a36Sopenharmony_ci#include "../../../util/debug.h"
1262306a36Sopenharmony_ci#include "../../../util/pmu.h"
1362306a36Sopenharmony_ci#include "../../../util/pmus.h"
1462306a36Sopenharmony_ci#include "../../../util/auxtrace.h"
1562306a36Sopenharmony_ci#include "../../../util/intel-pt.h"
1662306a36Sopenharmony_ci#include "../../../util/intel-bts.h"
1762306a36Sopenharmony_ci#include "../../../util/evlist.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic
2062306a36Sopenharmony_cistruct auxtrace_record *auxtrace_record__init_intel(struct evlist *evlist,
2162306a36Sopenharmony_ci						    int *err)
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	struct perf_pmu *intel_pt_pmu;
2462306a36Sopenharmony_ci	struct perf_pmu *intel_bts_pmu;
2562306a36Sopenharmony_ci	struct evsel *evsel;
2662306a36Sopenharmony_ci	bool found_pt = false;
2762306a36Sopenharmony_ci	bool found_bts = false;
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	intel_pt_pmu = perf_pmus__find(INTEL_PT_PMU_NAME);
3062306a36Sopenharmony_ci	intel_bts_pmu = perf_pmus__find(INTEL_BTS_PMU_NAME);
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	evlist__for_each_entry(evlist, evsel) {
3362306a36Sopenharmony_ci		if (intel_pt_pmu && evsel->core.attr.type == intel_pt_pmu->type)
3462306a36Sopenharmony_ci			found_pt = true;
3562306a36Sopenharmony_ci		if (intel_bts_pmu && evsel->core.attr.type == intel_bts_pmu->type)
3662306a36Sopenharmony_ci			found_bts = true;
3762306a36Sopenharmony_ci	}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	if (found_pt && found_bts) {
4062306a36Sopenharmony_ci		pr_err("intel_pt and intel_bts may not be used together\n");
4162306a36Sopenharmony_ci		*err = -EINVAL;
4262306a36Sopenharmony_ci		return NULL;
4362306a36Sopenharmony_ci	}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	if (found_pt)
4662306a36Sopenharmony_ci		return intel_pt_recording_init(err);
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	if (found_bts)
4962306a36Sopenharmony_ci		return intel_bts_recording_init(err);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	return NULL;
5262306a36Sopenharmony_ci}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistruct auxtrace_record *auxtrace_record__init(struct evlist *evlist,
5562306a36Sopenharmony_ci					      int *err)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	char buffer[64];
5862306a36Sopenharmony_ci	int ret;
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	*err = 0;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	ret = get_cpuid(buffer, sizeof(buffer));
6362306a36Sopenharmony_ci	if (ret) {
6462306a36Sopenharmony_ci		*err = ret;
6562306a36Sopenharmony_ci		return NULL;
6662306a36Sopenharmony_ci	}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	if (!strncmp(buffer, "GenuineIntel,", 13))
6962306a36Sopenharmony_ci		return auxtrace_record__init_intel(evlist, err);
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	return NULL;
7262306a36Sopenharmony_ci}
73