Reviewed-by: Mike Leach mike.leach@arm.com
On 9/24/26 18:33, Yeoreum Yun wrote:
The purpose of TRCSSCSRn register is to show status of the corresponding Single-shot Comparator Control and input supports. That means writable field's purpose for reset or restore from idle status not for configuration.
Therefore, exclude ss_status from drvdata->config and move it to drvdata.
Before this patch, clearing the PENDING and STATUS bits when enabling a perf session could trigger multiple single-shot events within the same session. This issue will be addressed in a future patch; this patch intentionally preserves the existing behavior.
Reviewed-by: Leo Yan leo.yan@arm.com Tested-by: Leo Yan leo.yan@arm.com Signed-off-by: Yeoreum Yun yeoreum.yun@arm.com
drivers/hwtracing/coresight/coresight-etm4x-cfg.c | 1 - drivers/hwtracing/coresight/coresight-etm4x-core.c | 18 +++++++----------- drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 10 +++++----- drivers/hwtracing/coresight/coresight-etm4x.h | 8 +++++++- 4 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c index a9f6ed47a2f5..52cb036bb04b 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c @@ -86,7 +86,6 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata, off_mask = (offset & GENMASK(11, 5)); do { CHECKREGIDX(TRCSSCCRn(0), ss_ctrl, idx, off_mask);
} while (0); } else if ((offset >= TRCCIDCVRn(0)) && (offset <= TRCVMIDCVRn(7))) {CHECKREGIDX(TRCSSCSRn(0), ss_status, idx, off_mask); CHECKREGIDX(TRCSSPCICRn(0), ss_pe_cmp, idx, off_mask);diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 3900b96e9c7c..4a8c1070bbcb 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -95,7 +95,7 @@ static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n) const struct etmv4_caps *caps = &drvdata->caps; return (n < caps->nr_ss_cmp) && caps->nr_pe_cmp &&
(drvdata->config.ss_status[n] & TRCSSCSRn_PC);
}(drvdata->ss_status[n] & TRCSSCSRn_PC);u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit) @@ -572,11 +572,11 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) etm4x_relaxed_write32(csa, config->res_ctrl[i], TRCRSCTLRn(i)); for (i = 0; i < caps->nr_ss_cmp; i++) {
/* always clear status bit on restart if using single-shot */
if (config->ss_ctrl[i] || config->ss_pe_cmp[i])/* always clear status and pending bits on restart if using single-shot */
config->ss_status[i] &= ~TRCSSCSRn_STATUS;
etm4x_relaxed_write32(csa, config->ss_ctrl[i], TRCSSCCRn(i));drvdata->ss_status[i] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
etm4x_relaxed_write32(csa, config->ss_status[i], TRCSSCSRn(i));
if (etm4x_sspcicrn_present(drvdata, i)) etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i)); }etm4x_relaxed_write32(csa, drvdata->ss_status[i], TRCSSCSRn(i));@@ -1078,7 +1078,7 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata) /* read the status of the single shot comparators */ for (i = 0; i < caps->nr_ss_cmp; i++) {
config->ss_status[i] =
}drvdata->ss_status[i] = etm4x_relaxed_read32(csa, TRCSSCSRn(i));@@ -1163,12 +1163,9 @@ static void etm4_disable_sysfs(struct coresight_device *csdev) drvdata, 1); /*
* Userspace may read ss_status and cntr_val through sysfs after
* Userspace may read cntr_val through sysfs after*/
- the sysfs-session has been disabled.
- for (i = 0; i < caps->nr_ss_cmp; i++)
config->ss_status[i] = curr_config->ss_status[i];- for (i = 0; i < caps->nr_cntr; i++) config->cntr_val[i] = curr_config->cntr_val[i];
@@ -1528,8 +1525,7 @@ static void etm4_init_arch_data(void *info) */ caps->nr_ss_cmp = FIELD_GET(TRCIDR4_NUMSSCC_MASK, etmidr4); for (i = 0; i < caps->nr_ss_cmp; i++) {
drvdata->config.ss_status[i] =etm4x_relaxed_read32(csa, TRCSSCSRn(i));
} /* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */ caps->numcidc = FIELD_GET(TRCIDR4_NUMCIDC_MASK, etmidr4);drvdata->ss_status[i] = etm4x_relaxed_read32(csa, TRCSSCSRn(i));diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c index 0f1f50b588f2..a66f34c942ba 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -1835,8 +1835,8 @@ static ssize_t sshot_ctrl_store(struct device *dev, raw_spin_lock(&drvdata->spinlock); idx = config->ss_idx; config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
- /* must clear bit 31 in related status register on programming */
- config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
- /* must clear bit 31 and 30 in related status register on programming */
- drvdata->ss_status[idx] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING); raw_spin_unlock(&drvdata->spinlock); return size; }
@@ -1850,7 +1850,7 @@ static ssize_t sshot_status_show(struct device *dev, struct etmv4_config *config = &drvdata->config; raw_spin_lock(&drvdata->spinlock);
- val = config->ss_status[config->ss_idx];
- val = drvdata->ss_status[config->ss_idx]; raw_spin_unlock(&drvdata->spinlock); return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); }
@@ -1885,8 +1885,8 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev, raw_spin_lock(&drvdata->spinlock); idx = config->ss_idx; config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
- /* must clear bit 31 in related status register on programming */
- config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
- /* must clear bit 31 and 30 in related status register on programming */
- drvdata->ss_status[idx] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING); raw_spin_unlock(&drvdata->spinlock); return size; }
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index b4579261868d..67071f7cbdbc 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -213,6 +213,11 @@ #define TRCACATRn_EXLEVEL_MASK GENMASK(14, 8) #define TRCSSCSRn_STATUS BIT(31) +/*
- TRCSSCSR.PENDING is only implemented by ETE and is therefore not
- described in DEN0117. See Arm ARM (DDI0487) M.c, section D24.4.59.
- */
+#define TRCSSCSRn_PENDING BIT(30) #define TRCSSCCRn_SAC_ARC_RST_MASK GENMASK(24, 0) #define TRCSSPCICRn_PC_MASK GENMASK(7, 0) @@ -980,7 +985,6 @@ struct etmv4_config { u32 res_ctrl[ETM_MAX_RES_SEL]; /* TRCRSCTLRn */ u8 ss_idx; u32 ss_ctrl[ETM_MAX_SS_CMP];
- u32 ss_status[ETM_MAX_SS_CMP]; u32 ss_pe_cmp[ETM_MAX_SS_CMP]; u8 addr_idx; u64 addr_val[ETM_MAX_SINGLE_ADDR_CMP];
@@ -1071,6 +1075,7 @@ struct etmv4_save_state {
- @config: structure holding sysfs mode configuration.
- @save_state: State to be preserved across power loss
- @paused: Indicates if the trace unit is paused.
*/ struct etmv4_drvdata {
- @ss_status: The status of the corresponding single-shot comparator.
- @arch_features: Bitmap of arch features of etmv4 devices.
@@ -1091,6 +1096,7 @@ struct etmv4_drvdata { struct etmv4_config curr_config; struct etmv4_config config; struct etmv4_save_state *save_state;
- u32 ss_status[ETM_MAX_SS_CMP]; DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX); };