[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