[PATCH 14/19] coresight: etm4x: Detect access early on the target CPU

Suzuki K Poulose suzuki.poulose at arm.com
Fri Sep 11 04:41:14 EDT 2020


In preparation to detect the support for system instruction
support, move the detection of the device access to the target
CPU.

Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 65 ++++++++++++++-----
 1 file changed, 50 insertions(+), 15 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 53687ec06db9..5880f105268f 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -56,6 +56,11 @@ static u64 etm4_get_access_type(struct etmv4_config *config);
 
 static enum cpuhp_state hp_online;
 
+struct etm_init_arg {
+	struct etmv4_drvdata	*drvdata;
+	struct csdev_access	*csa;
+};
+
 u64 etm4x_sysreg_read(struct csdev_access *csa,
 		      u32 offset,
 		      bool _relaxed,
@@ -689,6 +694,22 @@ static void etm_detect_lock_status(struct etmv4_drvdata *drvdata,
 	drvdata->os_lock_model = TRCOSLSR_OSM(os_lsr);
 }
 
+static bool etm_init_iomem_access(struct etmv4_drvdata *drvdata,
+				  struct csdev_access *csa)
+{
+	*csa = CSDEV_ACCESS_IOMEM(drvdata->base);
+	return true;
+}
+
+static bool etm_init_csdev_access(struct etmv4_drvdata *drvdata,
+				  struct csdev_access *csa)
+{
+	if (drvdata->base)
+		return etm_init_iomem_access(drvdata, csa);
+
+	return false;
+}
+
 static void etm4_init_arch_data(void *info)
 {
 	u32 etmidr0;
@@ -697,22 +718,34 @@ static void etm4_init_arch_data(void *info)
 	u32 etmidr3;
 	u32 etmidr4;
 	u32 etmidr5;
-	struct etmv4_drvdata *drvdata = info;
+	struct etm_init_arg *init_arg = info;
+	struct etmv4_drvdata *drvdata;
+	struct csdev_access *csa;
 	int i;
-	struct csdev_access csa = CSDEV_ACCESS_IOMEM(drvdata->base);
+
+	drvdata = init_arg->drvdata;
+	csa = init_arg->csa;
+
+	/*
+	 * If we are unable to detect the access mechanism,
+	 * or unable to detect the trace unit type, fail
+	 * early.
+	 */
+	if (!etm_init_csdev_access(drvdata, csa))
+		return;
 
 	/*
 	 * We must check if the locks are implemented
 	 * as early as possible.
 	 */
-	etm_detect_lock_status(drvdata, &csa);
+	etm_detect_lock_status(drvdata, csa);
 
 	/* Make sure all registers are accessible */
-	etm4_os_unlock_csa(drvdata, &csa);
-	etm4_cs_unlock(drvdata, &csa);
+	etm4_os_unlock_csa(drvdata, csa);
+	etm4_cs_unlock(drvdata, csa);
 
 	/* find all capabilities of the tracing unit */
-	etmidr0 = etm4x_relaxed_read32(&csa, TRCIDR0);
+	etmidr0 = etm4x_relaxed_read32(csa, TRCIDR0);
 
 	/* INSTP0, bits[2:1] P0 tracing support field */
 	if (BMVAL(etmidr0, 1, 1) && BMVAL(etmidr0, 2, 2))
@@ -752,7 +785,7 @@ static void etm4_init_arch_data(void *info)
 	drvdata->ts_size = BMVAL(etmidr0, 24, 28);
 
 	/* base architecture of trace unit */
-	etmidr1 = etm4x_relaxed_read32(&csa, TRCIDR1);
+	etmidr1 = etm4x_relaxed_read32(csa, TRCIDR1);
 	/*
 	 * TRCARCHMIN, bits[7:4] architecture the minor version number
 	 * TRCARCHMAJ, bits[11:8] architecture major versin number
@@ -760,7 +793,7 @@ static void etm4_init_arch_data(void *info)
 	drvdata->arch = BMVAL(etmidr1, 4, 11);
 
 	/* maximum size of resources */
-	etmidr2 = etm4x_relaxed_read32(&csa, TRCIDR2);
+	etmidr2 = etm4x_relaxed_read32(csa, TRCIDR2);
 	/* CIDSIZE, bits[9:5] Indicates the Context ID size */
 	drvdata->ctxid_size = BMVAL(etmidr2, 5, 9);
 	/* VMIDSIZE, bits[14:10] Indicates the VMID size */
@@ -768,7 +801,7 @@ static void etm4_init_arch_data(void *info)
 	/* CCSIZE, bits[28:25] size of the cycle counter in bits minus 12 */
 	drvdata->ccsize = BMVAL(etmidr2, 25, 28);
 
-	etmidr3 = etm4x_relaxed_read32(&csa, TRCIDR3);
+	etmidr3 = etm4x_relaxed_read32(csa, TRCIDR3);
 	/* CCITMIN, bits[11:0] minimum threshold value that can be programmed */
 	drvdata->ccitmin = BMVAL(etmidr3, 0, 11);
 	/* EXLEVEL_S, bits[19:16] Secure state instruction tracing */
@@ -814,7 +847,7 @@ static void etm4_init_arch_data(void *info)
 		drvdata->nooverflow = false;
 
 	/* number of resources trace unit supports */
-	etmidr4 = etm4x_relaxed_read32(&csa, TRCIDR4);
+	etmidr4 = etm4x_relaxed_read32(csa, TRCIDR4);
 	/* NUMACPAIRS, bits[0:3] number of addr comparator pairs for tracing */
 	drvdata->nr_addr_cmp = BMVAL(etmidr4, 0, 3);
 	/* NUMPC, bits[15:12] number of PE comparator inputs for tracing */
@@ -834,14 +867,14 @@ static void etm4_init_arch_data(void *info)
 	drvdata->nr_ss_cmp = BMVAL(etmidr4, 20, 23);
 	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
 		drvdata->config.ss_status[i] =
-			etm4x_relaxed_read32(&csa, TRCSSCSRn(i));
+			etm4x_relaxed_read32(csa, TRCSSCSRn(i));
 	}
 	/* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */
 	drvdata->numcidc = BMVAL(etmidr4, 24, 27);
 	/* NUMVMIDC, bits[31:28] number of VMID comparators for tracing */
 	drvdata->numvmidc = BMVAL(etmidr4, 28, 31);
 
-	etmidr5 = etm4x_relaxed_read32(&csa, TRCIDR5);
+	etmidr5 = etm4x_relaxed_read32(csa, TRCIDR5);
 	/* NUMEXTIN, bits[8:0] number of external inputs implemented */
 	drvdata->nr_ext_inp = BMVAL(etmidr5, 0, 8);
 	/* TRACEIDSIZE, bits[21:16] indicates the trace ID width */
@@ -864,7 +897,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);
+	etm4_cs_lock(drvdata, csa);
 }
 
 static inline u32 etm4_get_victlr_access_type(struct etmv4_config *config)
@@ -1538,6 +1571,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
 	struct etmv4_drvdata *drvdata;
 	struct resource *res = &adev->res;
 	struct coresight_desc desc = { 0 };
+	struct etm_init_arg init_arg = { 0 };
 
 	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
 	if (!drvdata)
@@ -1565,7 +1599,6 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
 		return PTR_ERR(base);
 
 	drvdata->base = base;
-	desc.access = CSDEV_ACCESS_IOMEM(base);
 
 	spin_lock_init(&drvdata->spinlock);
 
@@ -1578,9 +1611,11 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
 		return -ENOMEM;
 
 	etmdrvdata[drvdata->cpu] = drvdata;
+	init_arg.drvdata = drvdata;
+	init_arg.csa = &desc.access;
 
 	if (smp_call_function_single(drvdata->cpu,
-				etm4_init_arch_data,  drvdata, 1))
+				etm4_init_arch_data,  &init_arg, 1))
 		dev_err(dev, "ETM arch init failed\n");
 
 	if (etm4_arch_supported(drvdata->arch) == false) {
-- 
2.24.1




More information about the linux-arm-kernel mailing list