coresight: Add support for v8.4 SelfHosted tracing
authorJonathan Zhou <jonathan.zhouwen@huawei.com>
Mon, 1 Feb 2021 18:13:50 +0000 (11:13 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 4 Feb 2021 16:00:34 +0000 (17:00 +0100)
v8.4 tracing extensions added support for trace filtering controlled
by TRFCR_ELx. This must be programmed to allow tracing at EL1/EL2 and
EL0. The timestamp used is the virtual time. Also enable CONTEXIDR_EL2
tracing if we are running the kernel at EL2.

Link: https://lore.kernel.org/r/20210110224850.1880240-29-suzuki.poulose@arm.com
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: Will Deacon <will@kernel.org>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Jonathan Zhou <jonathan.zhouwen@huawei.com>
[ Move the trace filtering setup etm_init_arch_data() and clean ups]
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20210201181351.1475223-31-mathieu.poirier@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hwtracing/coresight/coresight-etm4x-core.c

index c6238e2..473ab74 100644 (file)
@@ -859,6 +859,30 @@ static bool etm4_init_csdev_access(struct etmv4_drvdata *drvdata,
        return false;
 }
 
+static void cpu_enable_tracing(void)
+{
+       u64 dfr0 = read_sysreg(id_aa64dfr0_el1);
+       u64 trfcr;
+
+       if (!cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_TRACE_FILT_SHIFT))
+               return;
+
+       /*
+        * If the CPU supports v8.4 SelfHosted Tracing, enable
+        * tracing at the kernel EL and EL0, forcing to use the
+        * virtual time as the timestamp.
+        */
+       trfcr = (TRFCR_ELx_TS_VIRTUAL |
+                TRFCR_ELx_ExTRE |
+                TRFCR_ELx_E0TRE);
+
+       /* If we are running at EL2, allow tracing the CONTEXTIDR_EL2. */
+       if (is_kernel_in_hyp_mode())
+               trfcr |= TRFCR_EL2_CX;
+
+       write_sysreg_s(trfcr, SYS_TRFCR_EL1);
+}
+
 static void etm4_init_arch_data(void *info)
 {
        u32 etmidr0;
@@ -1044,6 +1068,7 @@ static void etm4_init_arch_data(void *info)
        /* NUMCNTR, bits[30:28] number of counters available for tracing */
        drvdata->nr_cntr = BMVAL(etmidr5, 28, 30);
        etm4_cs_lock(drvdata, csa);
+       cpu_enable_tracing();
 }
 
 static inline u32 etm4_get_victlr_access_type(struct etmv4_config *config)