18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * auxtrace.c: AUX area tracing support
48c2ecf20Sopenharmony_ci * Copyright (c) 2013-2014, Intel Corporation.
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <errno.h>
88c2ecf20Sopenharmony_ci#include <stdbool.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "../../../util/header.h"
118c2ecf20Sopenharmony_ci#include "../../../util/debug.h"
128c2ecf20Sopenharmony_ci#include "../../../util/pmu.h"
138c2ecf20Sopenharmony_ci#include "../../../util/auxtrace.h"
148c2ecf20Sopenharmony_ci#include "../../../util/intel-pt.h"
158c2ecf20Sopenharmony_ci#include "../../../util/intel-bts.h"
168c2ecf20Sopenharmony_ci#include "../../../util/evlist.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic
198c2ecf20Sopenharmony_cistruct auxtrace_record *auxtrace_record__init_intel(struct evlist *evlist,
208c2ecf20Sopenharmony_ci						    int *err)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	struct perf_pmu *intel_pt_pmu;
238c2ecf20Sopenharmony_ci	struct perf_pmu *intel_bts_pmu;
248c2ecf20Sopenharmony_ci	struct evsel *evsel;
258c2ecf20Sopenharmony_ci	bool found_pt = false;
268c2ecf20Sopenharmony_ci	bool found_bts = false;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	intel_pt_pmu = perf_pmu__find(INTEL_PT_PMU_NAME);
298c2ecf20Sopenharmony_ci	if (intel_pt_pmu)
308c2ecf20Sopenharmony_ci		intel_pt_pmu->auxtrace = true;
318c2ecf20Sopenharmony_ci	intel_bts_pmu = perf_pmu__find(INTEL_BTS_PMU_NAME);
328c2ecf20Sopenharmony_ci	if (intel_bts_pmu)
338c2ecf20Sopenharmony_ci		intel_bts_pmu->auxtrace = true;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	evlist__for_each_entry(evlist, evsel) {
368c2ecf20Sopenharmony_ci		if (intel_pt_pmu && evsel->core.attr.type == intel_pt_pmu->type)
378c2ecf20Sopenharmony_ci			found_pt = true;
388c2ecf20Sopenharmony_ci		if (intel_bts_pmu && evsel->core.attr.type == intel_bts_pmu->type)
398c2ecf20Sopenharmony_ci			found_bts = true;
408c2ecf20Sopenharmony_ci	}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	if (found_pt && found_bts) {
438c2ecf20Sopenharmony_ci		pr_err("intel_pt and intel_bts may not be used together\n");
448c2ecf20Sopenharmony_ci		*err = -EINVAL;
458c2ecf20Sopenharmony_ci		return NULL;
468c2ecf20Sopenharmony_ci	}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	if (found_pt)
498c2ecf20Sopenharmony_ci		return intel_pt_recording_init(err);
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	if (found_bts)
528c2ecf20Sopenharmony_ci		return intel_bts_recording_init(err);
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	return NULL;
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistruct auxtrace_record *auxtrace_record__init(struct evlist *evlist,
588c2ecf20Sopenharmony_ci					      int *err)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	char buffer[64];
618c2ecf20Sopenharmony_ci	int ret;
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	*err = 0;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	ret = get_cpuid(buffer, sizeof(buffer));
668c2ecf20Sopenharmony_ci	if (ret) {
678c2ecf20Sopenharmony_ci		*err = ret;
688c2ecf20Sopenharmony_ci		return NULL;
698c2ecf20Sopenharmony_ci	}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	if (!strncmp(buffer, "GenuineIntel,", 13))
728c2ecf20Sopenharmony_ci		return auxtrace_record__init_intel(evlist, err);
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	return NULL;
758c2ecf20Sopenharmony_ci}
76