The TSC parameters are used for conversion between arch timer counter
and kernel timestamp, this patch stores the parameters into the struct
perf_record_auxtrace_info, and it is saved in perf data file.

Signed-off-by: Leo Yan <leo....@linaro.org>
---
 tools/perf/arch/arm64/util/arm-spe.c | 23 +++++++++++++++++++++++
 tools/perf/util/arm-spe.h            |  6 ++++++
 2 files changed, 29 insertions(+)

diff --git a/tools/perf/arch/arm64/util/arm-spe.c 
b/tools/perf/arch/arm64/util/arm-spe.c
index 414c8a5584b1..dd940cf16f49 100644
--- a/tools/perf/arch/arm64/util/arm-spe.c
+++ b/tools/perf/arch/arm64/util/arm-spe.c
@@ -15,7 +15,9 @@
 #include "../../../util/event.h"
 #include "../../../util/evsel.h"
 #include "../../../util/evlist.h"
+#include "../../../util/mmap.h"
 #include "../../../util/session.h"
+#include "../../../util/tsc.h"
 #include <internal/lib.h> // page_size
 #include "../../../util/pmu.h"
 #include "../../../util/debug.h"
@@ -47,6 +49,9 @@ static int arm_spe_info_fill(struct auxtrace_record *itr,
        struct arm_spe_recording *sper =
                        container_of(itr, struct arm_spe_recording, itr);
        struct perf_pmu *arm_spe_pmu = sper->arm_spe_pmu;
+       struct perf_event_mmap_page *pc;
+       struct perf_tsc_conversion tc = { .time_mult = 0, };
+       int err;
 
        if (priv_size != ARM_SPE_AUXTRACE_PRIV_SIZE)
                return -EINVAL;
@@ -54,8 +59,26 @@ static int arm_spe_info_fill(struct auxtrace_record *itr,
        if (!session->evlist->core.nr_mmaps)
                return -EINVAL;
 
+       pc = session->evlist->mmap[0].core.base;
+       if (pc) {
+               err = perf_read_tsc_conversion(pc, &tc);
+               if (err) {
+                       if (err != -EOPNOTSUPP)
+                               return err;
+               }
+
+               if (!tc.time_mult)
+                       ui__warning("Arm SPE: arch timer not available\n");
+       }
+
        auxtrace_info->type = PERF_AUXTRACE_ARM_SPE;
        auxtrace_info->priv[ARM_SPE_PMU_TYPE] = arm_spe_pmu->type;
+       auxtrace_info->priv[ARM_SPE_TIME_SHIFT] = tc.time_shift;
+       auxtrace_info->priv[ARM_SPE_TIME_MULT] = tc.time_mult;
+       auxtrace_info->priv[ARM_SPE_TIME_ZERO] = tc.time_zero;
+       auxtrace_info->priv[ARM_SPE_TIME_CYCLES] = tc.time_cycles;
+       auxtrace_info->priv[ARM_SPE_TIME_MASK] = tc.time_mask;
+       auxtrace_info->priv[ARM_SPE_CAP_USER_TIME_SHORT] = 
tc.cap_user_time_short;
 
        return 0;
 }
diff --git a/tools/perf/util/arm-spe.h b/tools/perf/util/arm-spe.h
index 105ce0ea0a01..5bf3e838d226 100644
--- a/tools/perf/util/arm-spe.h
+++ b/tools/perf/util/arm-spe.h
@@ -11,6 +11,12 @@
 
 enum {
        ARM_SPE_PMU_TYPE,
+       ARM_SPE_TIME_SHIFT,
+       ARM_SPE_TIME_MULT,
+       ARM_SPE_TIME_ZERO,
+       ARM_SPE_TIME_CYCLES,
+       ARM_SPE_TIME_MASK,
+       ARM_SPE_CAP_USER_TIME_SHORT,
        ARM_SPE_AUXTRACE_PRIV_MAX,
 };
 
-- 
2.25.1

Reply via email to