Coresight changes for v5.19
This pull request includes: - Work to uniformise access to the ETMv4 registers, making it easier to look for and change register accesses. - A correction to a probing failure when looking for links between devices. - The replacement of a call to mutex_lock() with a mutex_trylock() in the panic notifier of the cpu-debug infrastructure to avoid a possible deadlock. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> -----BEGIN PGP SIGNATURE----- iQFPBAABCgA5FiEEeTrpXvBwUkra1RYWo5FxFnwrV6EFAmJ+iwMbHG1hdGhpZXUu cG9pcmllckBsaW5hcm8ub3JnAAoJEKORcRZ8K1ehNv8IAIM/3MxCM4hk/quuzGEy L1unk2tQRcn1KoCSjYV4InODf84oBuIIhw24vL1Eh/XaTkv0lg1uy253MgAep7ck DdpikxUnEJE+tkfvqzjIrIThSV4ybRMVEIWcx8AkLD0T3KjKFnmoNmsuwOe4N0BK ME8HfCyRfdzkEVT8FtGpXPQl4EO+PtOa9TdHNCWNC5/abRJFGDXH0IaPVYouC/Zc 7YO7s9ANdw+vYYDHAUjE59jv8UjeaOeA5YLzDRnUjREwe1ylW9agjToWotk3sTKV p6iznyFodw4Tfjp3I38tCouL+lLEV3OOzDxRT0oa4npJUjY/SyO+RXmvZ0qEMnev BjE= =v5uO -----END PGP SIGNATURE----- Merge tag 'coresight-next-v5.19' of gitolite.kernel.org:pub/scm/linux/kernel/git/coresight/linux into char-misc-next Mathieu writes: Coresight changes for v5.19 This pull request includes: - Work to uniformise access to the ETMv4 registers, making it easier to look for and change register accesses. - A correction to a probing failure when looking for links between devices. - The replacement of a call to mutex_lock() with a mutex_trylock() in the panic notifier of the cpu-debug infrastructure to avoid a possible deadlock. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> * tag 'coresight-next-v5.19' of gitolite.kernel.org:pub/scm/linux/kernel/git/coresight/linux: coresight: cpu-debug: Replace mutex with mutex_trylock on panic notifier coresight: core: Fix coresight device probe failure issue coresight: etm4x: Cleanup TRCRSCTLRn register accesses coresight: etm4x: Cleanup TRCBBCTLR register accesses coresight: etm4x: Cleanup TRCSSPCICRn register accesses coresight: etm4x: Cleanup TRCSSCCRn and TRCSSCSRn register accesses coresight: etm4x: Cleanup TRCACATRn register accesses coresight: etm3x: Cleanup ETMTECR1 register accesses coresight: etm4x: Cleanup TRCVICTLR register accesses coresight: etm4x: Cleanup TRCSTALLCTLR register accesses coresight: etm4x: Cleanup TRCEVENTCTL1R register accesses coresight: etm4x: Cleanup TRCCONFIGR register accesses coresight: etm4x: Cleanup TRCIDR5 register accesses coresight: etm4x: Cleanup TRCIDR4 register accesses coresight: etm4x: Cleanup TRCIDR3 register accesses coresight: etm4x: Cleanup TRCIDR2 register accesses coresight: etm4x: Cleanup TRCIDR0 register accesses
This commit is contained in:
commit
9c518db640
|
@ -1379,7 +1379,7 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev)
|
|||
continue;
|
||||
conn->child_dev =
|
||||
coresight_find_csdev_by_fwnode(conn->child_fwnode);
|
||||
if (conn->child_dev) {
|
||||
if (conn->child_dev && conn->child_dev->has_conns_grp) {
|
||||
ret = coresight_make_links(csdev, conn,
|
||||
conn->child_dev);
|
||||
if (ret)
|
||||
|
@ -1571,6 +1571,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
|
|||
int nr_refcnts = 1;
|
||||
atomic_t *refcnts = NULL;
|
||||
struct coresight_device *csdev;
|
||||
bool registered = false;
|
||||
|
||||
csdev = kzalloc(sizeof(*csdev), GFP_KERNEL);
|
||||
if (!csdev) {
|
||||
|
@ -1591,7 +1592,8 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
|
|||
refcnts = kcalloc(nr_refcnts, sizeof(*refcnts), GFP_KERNEL);
|
||||
if (!refcnts) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_csdev;
|
||||
kfree(csdev);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
csdev->refcnt = refcnts;
|
||||
|
@ -1616,6 +1618,13 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
|
|||
csdev->dev.fwnode = fwnode_handle_get(dev_fwnode(desc->dev));
|
||||
dev_set_name(&csdev->dev, "%s", desc->name);
|
||||
|
||||
/*
|
||||
* Make sure the device registration and the connection fixup
|
||||
* are synchronised, so that we don't see uninitialised devices
|
||||
* on the coresight bus while trying to resolve the connections.
|
||||
*/
|
||||
mutex_lock(&coresight_mutex);
|
||||
|
||||
ret = device_register(&csdev->dev);
|
||||
if (ret) {
|
||||
put_device(&csdev->dev);
|
||||
|
@ -1623,7 +1632,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
|
|||
* All resources are free'd explicitly via
|
||||
* coresight_device_release(), triggered from put_device().
|
||||
*/
|
||||
goto err_out;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (csdev->type == CORESIGHT_DEV_TYPE_SINK ||
|
||||
|
@ -1638,11 +1647,11 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
|
|||
* from put_device(), which is in turn called from
|
||||
* function device_unregister().
|
||||
*/
|
||||
goto err_out;
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&coresight_mutex);
|
||||
/* Device is now registered */
|
||||
registered = true;
|
||||
|
||||
ret = coresight_create_conns_sysfs_group(csdev);
|
||||
if (!ret)
|
||||
|
@ -1652,16 +1661,18 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
|
|||
if (!ret && cti_assoc_ops && cti_assoc_ops->add)
|
||||
cti_assoc_ops->add(csdev);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&coresight_mutex);
|
||||
if (ret) {
|
||||
/* Success */
|
||||
if (!ret)
|
||||
return csdev;
|
||||
|
||||
/* Unregister the device if needed */
|
||||
if (registered) {
|
||||
coresight_unregister(csdev);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return csdev;
|
||||
|
||||
err_free_csdev:
|
||||
kfree(csdev);
|
||||
err_out:
|
||||
/* Cleanup the connection information */
|
||||
coresight_release_platform_data(NULL, desc->pdata);
|
||||
|
|
|
@ -380,9 +380,10 @@ static int debug_notifier_call(struct notifier_block *self,
|
|||
int cpu;
|
||||
struct debug_drvdata *drvdata;
|
||||
|
||||
mutex_lock(&debug_lock);
|
||||
/* Bail out if we can't acquire the mutex or the functionality is off */
|
||||
if (!mutex_trylock(&debug_lock))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
/* Bail out if the functionality is disabled */
|
||||
if (!debug_enable)
|
||||
goto skip_dump;
|
||||
|
||||
|
@ -401,7 +402,7 @@ static int debug_notifier_call(struct notifier_block *self,
|
|||
|
||||
skip_dump:
|
||||
mutex_unlock(&debug_lock);
|
||||
return 0;
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block debug_notifier = {
|
||||
|
|
|
@ -204,7 +204,7 @@ void etm_set_default(struct etm_config *config)
|
|||
* set all bits in register 0x007, the ETMTECR2, to 0
|
||||
* set register 0x008, the ETMTEEVR, to 0x6F (TRUE).
|
||||
*/
|
||||
config->enable_ctrl1 = BIT(24);
|
||||
config->enable_ctrl1 = ETMTECR1_INC_EXC;
|
||||
config->enable_ctrl2 = 0x0;
|
||||
config->enable_event = ETM_HARD_WIRE_RES_A;
|
||||
|
||||
|
|
|
@ -474,7 +474,7 @@ static ssize_t addr_start_store(struct device *dev,
|
|||
config->addr_val[idx] = val;
|
||||
config->addr_type[idx] = ETM_ADDR_TYPE_START;
|
||||
config->startstop_ctrl |= (1 << idx);
|
||||
config->enable_ctrl1 |= BIT(25);
|
||||
config->enable_ctrl1 |= ETMTECR1_START_STOP;
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
|
||||
return size;
|
||||
|
|
|
@ -443,7 +443,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
|
|||
for (i = 0; i < drvdata->nr_ss_cmp; i++) {
|
||||
/* always clear status bit on restart if using single-shot */
|
||||
if (config->ss_ctrl[i] || config->ss_pe_cmp[i])
|
||||
config->ss_status[i] &= ~BIT(31);
|
||||
config->ss_status[i] &= ~TRCSSCSRn_STATUS;
|
||||
etm4x_relaxed_write32(csa, config->ss_ctrl[i], TRCSSCCRn(i));
|
||||
etm4x_relaxed_write32(csa, config->ss_status[i], TRCSSCSRn(i));
|
||||
if (etm4x_sspcicrn_present(drvdata, i))
|
||||
|
@ -633,7 +633,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
|
|||
|
||||
/* Go from generic option to ETMv4 specifics */
|
||||
if (attr->config & BIT(ETM_OPT_CYCACC)) {
|
||||
config->cfg |= BIT(4);
|
||||
config->cfg |= TRCCONFIGR_CCI;
|
||||
/* TRM: Must program this for cycacc to work */
|
||||
config->ccctlr = ETM_CYC_THRESHOLD_DEFAULT;
|
||||
}
|
||||
|
@ -653,14 +653,14 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
|
|||
goto out;
|
||||
|
||||
/* bit[11], Global timestamp tracing bit */
|
||||
config->cfg |= BIT(11);
|
||||
config->cfg |= TRCCONFIGR_TS;
|
||||
}
|
||||
|
||||
/* Only trace contextID when runs in root PID namespace */
|
||||
if ((attr->config & BIT(ETM_OPT_CTXTID)) &&
|
||||
task_is_in_init_pid_ns(current))
|
||||
/* bit[6], Context ID tracing bit */
|
||||
config->cfg |= BIT(ETM4_CFG_BIT_CTXTID);
|
||||
config->cfg |= TRCCONFIGR_CID;
|
||||
|
||||
/*
|
||||
* If set bit ETM_OPT_CTXTID2 in perf config, this asks to trace VMID
|
||||
|
@ -672,17 +672,15 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
|
|||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Only trace virtual contextID when runs in root PID namespace */
|
||||
if (task_is_in_init_pid_ns(current))
|
||||
config->cfg |= BIT(ETM4_CFG_BIT_VMID) |
|
||||
BIT(ETM4_CFG_BIT_VMID_OPT);
|
||||
config->cfg |= TRCCONFIGR_VMID | TRCCONFIGR_VMIDOPT;
|
||||
}
|
||||
|
||||
/* return stack - enable if selected and supported */
|
||||
if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack)
|
||||
/* bit[12], Return stack enable bit */
|
||||
config->cfg |= BIT(12);
|
||||
config->cfg |= TRCCONFIGR_RS;
|
||||
|
||||
/*
|
||||
* Set any selected configuration and preset.
|
||||
|
@ -1097,107 +1095,67 @@ static void etm4_init_arch_data(void *info)
|
|||
etmidr0 = etm4x_relaxed_read32(csa, TRCIDR0);
|
||||
|
||||
/* INSTP0, bits[2:1] P0 tracing support field */
|
||||
if (BMVAL(etmidr0, 1, 2) == 0b11)
|
||||
drvdata->instrp0 = true;
|
||||
else
|
||||
drvdata->instrp0 = false;
|
||||
|
||||
drvdata->instrp0 = !!(FIELD_GET(TRCIDR0_INSTP0_MASK, etmidr0) == 0b11);
|
||||
/* TRCBB, bit[5] Branch broadcast tracing support bit */
|
||||
if (BMVAL(etmidr0, 5, 5))
|
||||
drvdata->trcbb = true;
|
||||
else
|
||||
drvdata->trcbb = false;
|
||||
|
||||
drvdata->trcbb = !!(etmidr0 & TRCIDR0_TRCBB);
|
||||
/* TRCCOND, bit[6] Conditional instruction tracing support bit */
|
||||
if (BMVAL(etmidr0, 6, 6))
|
||||
drvdata->trccond = true;
|
||||
else
|
||||
drvdata->trccond = false;
|
||||
|
||||
drvdata->trccond = !!(etmidr0 & TRCIDR0_TRCCOND);
|
||||
/* TRCCCI, bit[7] Cycle counting instruction bit */
|
||||
if (BMVAL(etmidr0, 7, 7))
|
||||
drvdata->trccci = true;
|
||||
else
|
||||
drvdata->trccci = false;
|
||||
|
||||
drvdata->trccci = !!(etmidr0 & TRCIDR0_TRCCCI);
|
||||
/* RETSTACK, bit[9] Return stack bit */
|
||||
if (BMVAL(etmidr0, 9, 9))
|
||||
drvdata->retstack = true;
|
||||
else
|
||||
drvdata->retstack = false;
|
||||
|
||||
drvdata->retstack = !!(etmidr0 & TRCIDR0_RETSTACK);
|
||||
/* NUMEVENT, bits[11:10] Number of events field */
|
||||
drvdata->nr_event = BMVAL(etmidr0, 10, 11);
|
||||
drvdata->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0);
|
||||
/* QSUPP, bits[16:15] Q element support field */
|
||||
drvdata->q_support = BMVAL(etmidr0, 15, 16);
|
||||
drvdata->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0);
|
||||
/* TSSIZE, bits[28:24] Global timestamp size field */
|
||||
drvdata->ts_size = BMVAL(etmidr0, 24, 28);
|
||||
drvdata->ts_size = FIELD_GET(TRCIDR0_TSSIZE_MASK, etmidr0);
|
||||
|
||||
/* maximum size of resources */
|
||||
etmidr2 = etm4x_relaxed_read32(csa, TRCIDR2);
|
||||
/* CIDSIZE, bits[9:5] Indicates the Context ID size */
|
||||
drvdata->ctxid_size = BMVAL(etmidr2, 5, 9);
|
||||
drvdata->ctxid_size = FIELD_GET(TRCIDR2_CIDSIZE_MASK, etmidr2);
|
||||
/* VMIDSIZE, bits[14:10] Indicates the VMID size */
|
||||
drvdata->vmid_size = BMVAL(etmidr2, 10, 14);
|
||||
drvdata->vmid_size = FIELD_GET(TRCIDR2_VMIDSIZE_MASK, etmidr2);
|
||||
/* CCSIZE, bits[28:25] size of the cycle counter in bits minus 12 */
|
||||
drvdata->ccsize = BMVAL(etmidr2, 25, 28);
|
||||
drvdata->ccsize = FIELD_GET(TRCIDR2_CCSIZE_MASK, etmidr2);
|
||||
|
||||
etmidr3 = etm4x_relaxed_read32(csa, TRCIDR3);
|
||||
/* CCITMIN, bits[11:0] minimum threshold value that can be programmed */
|
||||
drvdata->ccitmin = BMVAL(etmidr3, 0, 11);
|
||||
drvdata->ccitmin = FIELD_GET(TRCIDR3_CCITMIN_MASK, etmidr3);
|
||||
/* EXLEVEL_S, bits[19:16] Secure state instruction tracing */
|
||||
drvdata->s_ex_level = BMVAL(etmidr3, 16, 19);
|
||||
drvdata->s_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_S_MASK, etmidr3);
|
||||
drvdata->config.s_ex_level = drvdata->s_ex_level;
|
||||
/* EXLEVEL_NS, bits[23:20] Non-secure state instruction tracing */
|
||||
drvdata->ns_ex_level = BMVAL(etmidr3, 20, 23);
|
||||
|
||||
drvdata->ns_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_NS_MASK, etmidr3);
|
||||
/*
|
||||
* TRCERR, bit[24] whether a trace unit can trace a
|
||||
* system error exception.
|
||||
*/
|
||||
if (BMVAL(etmidr3, 24, 24))
|
||||
drvdata->trc_error = true;
|
||||
else
|
||||
drvdata->trc_error = false;
|
||||
|
||||
drvdata->trc_error = !!(etmidr3 & TRCIDR3_TRCERR);
|
||||
/* SYNCPR, bit[25] implementation has a fixed synchronization period? */
|
||||
if (BMVAL(etmidr3, 25, 25))
|
||||
drvdata->syncpr = true;
|
||||
else
|
||||
drvdata->syncpr = false;
|
||||
|
||||
drvdata->syncpr = !!(etmidr3 & TRCIDR3_SYNCPR);
|
||||
/* STALLCTL, bit[26] is stall control implemented? */
|
||||
if (BMVAL(etmidr3, 26, 26))
|
||||
drvdata->stallctl = true;
|
||||
else
|
||||
drvdata->stallctl = false;
|
||||
|
||||
drvdata->stallctl = !!(etmidr3 & TRCIDR3_STALLCTL);
|
||||
/* SYSSTALL, bit[27] implementation can support stall control? */
|
||||
if (BMVAL(etmidr3, 27, 27))
|
||||
drvdata->sysstall = true;
|
||||
else
|
||||
drvdata->sysstall = false;
|
||||
|
||||
drvdata->sysstall = !!(etmidr3 & TRCIDR3_SYSSTALL);
|
||||
/*
|
||||
* NUMPROC - the number of PEs available for tracing, 5bits
|
||||
* = TRCIDR3.bits[13:12]bits[30:28]
|
||||
* bits[4:3] = TRCIDR3.bits[13:12] (since etm-v4.2, otherwise RES0)
|
||||
* bits[3:0] = TRCIDR3.bits[30:28]
|
||||
*/
|
||||
drvdata->nr_pe = (BMVAL(etmidr3, 12, 13) << 3) | BMVAL(etmidr3, 28, 30);
|
||||
|
||||
drvdata->nr_pe = (FIELD_GET(TRCIDR3_NUMPROC_HI_MASK, etmidr3) << 3) |
|
||||
FIELD_GET(TRCIDR3_NUMPROC_LO_MASK, etmidr3);
|
||||
/* NOOVERFLOW, bit[31] is trace overflow prevention supported */
|
||||
if (BMVAL(etmidr3, 31, 31))
|
||||
drvdata->nooverflow = true;
|
||||
else
|
||||
drvdata->nooverflow = false;
|
||||
drvdata->nooverflow = !!(etmidr3 & TRCIDR3_NOOVERFLOW);
|
||||
|
||||
/* number of resources trace unit supports */
|
||||
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);
|
||||
drvdata->nr_addr_cmp = FIELD_GET(TRCIDR4_NUMACPAIRS_MASK, etmidr4);
|
||||
/* NUMPC, bits[15:12] number of PE comparator inputs for tracing */
|
||||
drvdata->nr_pe_cmp = BMVAL(etmidr4, 12, 15);
|
||||
drvdata->nr_pe_cmp = FIELD_GET(TRCIDR4_NUMPC_MASK, etmidr4);
|
||||
/*
|
||||
* NUMRSPAIR, bits[19:16]
|
||||
* The number of resource pairs conveyed by the HW starts at 0, i.e a
|
||||
|
@ -1208,7 +1166,7 @@ static void etm4_init_arch_data(void *info)
|
|||
* the default TRUE and FALSE resource selectors are omitted.
|
||||
* Otherwise for values 0x1 and above the number is N + 1 as per v4.2.
|
||||
*/
|
||||
drvdata->nr_resource = BMVAL(etmidr4, 16, 19);
|
||||
drvdata->nr_resource = FIELD_GET(TRCIDR4_NUMRSPAIR_MASK, etmidr4);
|
||||
if ((drvdata->arch < ETM_ARCH_V4_3) || (drvdata->nr_resource > 0))
|
||||
drvdata->nr_resource += 1;
|
||||
/*
|
||||
|
@ -1216,45 +1174,39 @@ static void etm4_init_arch_data(void *info)
|
|||
* comparator control for tracing. Read any status regs as these
|
||||
* also contain RO capability data.
|
||||
*/
|
||||
drvdata->nr_ss_cmp = BMVAL(etmidr4, 20, 23);
|
||||
drvdata->nr_ss_cmp = FIELD_GET(TRCIDR4_NUMSSCC_MASK, etmidr4);
|
||||
for (i = 0; i < drvdata->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 */
|
||||
drvdata->numcidc = BMVAL(etmidr4, 24, 27);
|
||||
drvdata->numcidc = FIELD_GET(TRCIDR4_NUMCIDC_MASK, etmidr4);
|
||||
/* NUMVMIDC, bits[31:28] number of VMID comparators for tracing */
|
||||
drvdata->numvmidc = BMVAL(etmidr4, 28, 31);
|
||||
drvdata->numvmidc = FIELD_GET(TRCIDR4_NUMVMIDC_MASK, etmidr4);
|
||||
|
||||
etmidr5 = etm4x_relaxed_read32(csa, TRCIDR5);
|
||||
/* NUMEXTIN, bits[8:0] number of external inputs implemented */
|
||||
drvdata->nr_ext_inp = BMVAL(etmidr5, 0, 8);
|
||||
drvdata->nr_ext_inp = FIELD_GET(TRCIDR5_NUMEXTIN_MASK, etmidr5);
|
||||
/* TRACEIDSIZE, bits[21:16] indicates the trace ID width */
|
||||
drvdata->trcid_size = BMVAL(etmidr5, 16, 21);
|
||||
drvdata->trcid_size = FIELD_GET(TRCIDR5_TRACEIDSIZE_MASK, etmidr5);
|
||||
/* ATBTRIG, bit[22] implementation can support ATB triggers? */
|
||||
if (BMVAL(etmidr5, 22, 22))
|
||||
drvdata->atbtrig = true;
|
||||
else
|
||||
drvdata->atbtrig = false;
|
||||
drvdata->atbtrig = !!(etmidr5 & TRCIDR5_ATBTRIG);
|
||||
/*
|
||||
* LPOVERRIDE, bit[23] implementation supports
|
||||
* low-power state override
|
||||
*/
|
||||
if (BMVAL(etmidr5, 23, 23) && (!drvdata->skip_power_up))
|
||||
drvdata->lpoverride = true;
|
||||
else
|
||||
drvdata->lpoverride = false;
|
||||
drvdata->lpoverride = (etmidr5 & TRCIDR5_LPOVERRIDE) && (!drvdata->skip_power_up);
|
||||
/* NUMSEQSTATE, bits[27:25] number of sequencer states implemented */
|
||||
drvdata->nrseqstate = BMVAL(etmidr5, 25, 27);
|
||||
drvdata->nrseqstate = FIELD_GET(TRCIDR5_NUMSEQSTATE_MASK, etmidr5);
|
||||
/* NUMCNTR, bits[30:28] number of counters available for tracing */
|
||||
drvdata->nr_cntr = BMVAL(etmidr5, 28, 30);
|
||||
drvdata->nr_cntr = FIELD_GET(TRCIDR5_NUMCNTR_MASK, etmidr5);
|
||||
etm4_cs_lock(drvdata, csa);
|
||||
cpu_detect_trace_filtering(drvdata);
|
||||
}
|
||||
|
||||
static inline u32 etm4_get_victlr_access_type(struct etmv4_config *config)
|
||||
{
|
||||
return etm4_get_access_type(config) << TRCVICTLR_EXLEVEL_SHIFT;
|
||||
return etm4_get_access_type(config) << __bf_shf(TRCVICTLR_EXLEVEL_MASK);
|
||||
}
|
||||
|
||||
/* Set ELx trace filter access in the TRCVICTLR register */
|
||||
|
@ -1280,7 +1232,7 @@ static void etm4_set_default_config(struct etmv4_config *config)
|
|||
config->ts_ctrl = 0x0;
|
||||
|
||||
/* TRCVICTLR::EVENT = 0x01, select the always on logic */
|
||||
config->vinst_ctrl = BIT(0);
|
||||
config->vinst_ctrl = FIELD_PREP(TRCVICTLR_EVENT_MASK, 0x01);
|
||||
|
||||
/* TRCVICTLR::EXLEVEL_NS:EXLEVELS: Set kernel / user filtering */
|
||||
etm4_set_victlr_access(config);
|
||||
|
@ -1389,7 +1341,7 @@ static void etm4_set_default_filter(struct etmv4_config *config)
|
|||
* TRCVICTLR::SSSTATUS == 1, the start-stop logic is
|
||||
* in the started state
|
||||
*/
|
||||
config->vinst_ctrl |= BIT(9);
|
||||
config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
|
||||
config->mode |= ETM_MODE_VIEWINST_STARTSTOP;
|
||||
|
||||
/* No start-stop filtering for ViewInst */
|
||||
|
@ -1493,7 +1445,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
|
|||
* TRCVICTLR::SSSTATUS == 1, the start-stop logic is
|
||||
* in the started state
|
||||
*/
|
||||
config->vinst_ctrl |= BIT(9);
|
||||
config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
|
||||
|
||||
/* No start-stop filtering for ViewInst */
|
||||
config->vissctlr = 0x0;
|
||||
|
@ -1521,7 +1473,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
|
|||
* etm4_disable_perf().
|
||||
*/
|
||||
if (filters->ssstatus)
|
||||
config->vinst_ctrl |= BIT(9);
|
||||
config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
|
||||
|
||||
/* No include/exclude filtering for ViewInst */
|
||||
config->viiectlr = 0x0;
|
||||
|
|
|
@ -22,7 +22,7 @@ static int etm4_set_mode_exclude(struct etmv4_drvdata *drvdata, bool exclude)
|
|||
* TRCACATRn.TYPE bit[1:0]: type of comparison
|
||||
* the trace unit performs
|
||||
*/
|
||||
if (BMVAL(config->addr_acc[idx], 0, 1) == ETM_INSTR_ADDR) {
|
||||
if (FIELD_GET(TRCACATRn_TYPE_MASK, config->addr_acc[idx]) == TRCACATRn_TYPE_ADDR) {
|
||||
if (idx % 2 != 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -180,12 +180,12 @@ static ssize_t reset_store(struct device *dev,
|
|||
|
||||
/* Disable data tracing: do not trace load and store data transfers */
|
||||
config->mode &= ~(ETM_MODE_LOAD | ETM_MODE_STORE);
|
||||
config->cfg &= ~(BIT(1) | BIT(2));
|
||||
config->cfg &= ~(TRCCONFIGR_INSTP0_LOAD | TRCCONFIGR_INSTP0_STORE);
|
||||
|
||||
/* Disable data value and data address tracing */
|
||||
config->mode &= ~(ETM_MODE_DATA_TRACE_ADDR |
|
||||
ETM_MODE_DATA_TRACE_VAL);
|
||||
config->cfg &= ~(BIT(16) | BIT(17));
|
||||
config->cfg &= ~(TRCCONFIGR_DA | TRCCONFIGR_DV);
|
||||
|
||||
/* Disable all events tracing */
|
||||
config->eventctrl0 = 0x0;
|
||||
|
@ -206,11 +206,11 @@ static ssize_t reset_store(struct device *dev,
|
|||
* started state. ARM recommends start-stop logic is set before
|
||||
* each trace run.
|
||||
*/
|
||||
config->vinst_ctrl = BIT(0);
|
||||
config->vinst_ctrl = FIELD_PREP(TRCVICTLR_EVENT_MASK, 0x01);
|
||||
if (drvdata->nr_addr_cmp > 0) {
|
||||
config->mode |= ETM_MODE_VIEWINST_STARTSTOP;
|
||||
/* SSSTATUS, bit[9] */
|
||||
config->vinst_ctrl |= BIT(9);
|
||||
config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
|
||||
}
|
||||
|
||||
/* No address range filtering for ViewInst */
|
||||
|
@ -304,134 +304,134 @@ static ssize_t mode_store(struct device *dev,
|
|||
|
||||
if (drvdata->instrp0 == true) {
|
||||
/* start by clearing instruction P0 field */
|
||||
config->cfg &= ~(BIT(1) | BIT(2));
|
||||
config->cfg &= ~TRCCONFIGR_INSTP0_LOAD_STORE;
|
||||
if (config->mode & ETM_MODE_LOAD)
|
||||
/* 0b01 Trace load instructions as P0 instructions */
|
||||
config->cfg |= BIT(1);
|
||||
config->cfg |= TRCCONFIGR_INSTP0_LOAD;
|
||||
if (config->mode & ETM_MODE_STORE)
|
||||
/* 0b10 Trace store instructions as P0 instructions */
|
||||
config->cfg |= BIT(2);
|
||||
config->cfg |= TRCCONFIGR_INSTP0_STORE;
|
||||
if (config->mode & ETM_MODE_LOAD_STORE)
|
||||
/*
|
||||
* 0b11 Trace load and store instructions
|
||||
* as P0 instructions
|
||||
*/
|
||||
config->cfg |= BIT(1) | BIT(2);
|
||||
config->cfg |= TRCCONFIGR_INSTP0_LOAD_STORE;
|
||||
}
|
||||
|
||||
/* bit[3], Branch broadcast mode */
|
||||
if ((config->mode & ETM_MODE_BB) && (drvdata->trcbb == true))
|
||||
config->cfg |= BIT(3);
|
||||
config->cfg |= TRCCONFIGR_BB;
|
||||
else
|
||||
config->cfg &= ~BIT(3);
|
||||
config->cfg &= ~TRCCONFIGR_BB;
|
||||
|
||||
/* bit[4], Cycle counting instruction trace bit */
|
||||
if ((config->mode & ETMv4_MODE_CYCACC) &&
|
||||
(drvdata->trccci == true))
|
||||
config->cfg |= BIT(4);
|
||||
config->cfg |= TRCCONFIGR_CCI;
|
||||
else
|
||||
config->cfg &= ~BIT(4);
|
||||
config->cfg &= ~TRCCONFIGR_CCI;
|
||||
|
||||
/* bit[6], Context ID tracing bit */
|
||||
if ((config->mode & ETMv4_MODE_CTXID) && (drvdata->ctxid_size))
|
||||
config->cfg |= BIT(6);
|
||||
config->cfg |= TRCCONFIGR_CID;
|
||||
else
|
||||
config->cfg &= ~BIT(6);
|
||||
config->cfg &= ~TRCCONFIGR_CID;
|
||||
|
||||
if ((config->mode & ETM_MODE_VMID) && (drvdata->vmid_size))
|
||||
config->cfg |= BIT(7);
|
||||
config->cfg |= TRCCONFIGR_VMID;
|
||||
else
|
||||
config->cfg &= ~BIT(7);
|
||||
config->cfg &= ~TRCCONFIGR_VMID;
|
||||
|
||||
/* bits[10:8], Conditional instruction tracing bit */
|
||||
mode = ETM_MODE_COND(config->mode);
|
||||
if (drvdata->trccond == true) {
|
||||
config->cfg &= ~(BIT(8) | BIT(9) | BIT(10));
|
||||
config->cfg |= mode << 8;
|
||||
config->cfg &= ~TRCCONFIGR_COND_MASK;
|
||||
config->cfg |= mode << __bf_shf(TRCCONFIGR_COND_MASK);
|
||||
}
|
||||
|
||||
/* bit[11], Global timestamp tracing bit */
|
||||
if ((config->mode & ETMv4_MODE_TIMESTAMP) && (drvdata->ts_size))
|
||||
config->cfg |= BIT(11);
|
||||
config->cfg |= TRCCONFIGR_TS;
|
||||
else
|
||||
config->cfg &= ~BIT(11);
|
||||
config->cfg &= ~TRCCONFIGR_TS;
|
||||
|
||||
/* bit[12], Return stack enable bit */
|
||||
if ((config->mode & ETM_MODE_RETURNSTACK) &&
|
||||
(drvdata->retstack == true))
|
||||
config->cfg |= BIT(12);
|
||||
config->cfg |= TRCCONFIGR_RS;
|
||||
else
|
||||
config->cfg &= ~BIT(12);
|
||||
config->cfg &= ~TRCCONFIGR_RS;
|
||||
|
||||
/* bits[14:13], Q element enable field */
|
||||
mode = ETM_MODE_QELEM(config->mode);
|
||||
/* start by clearing QE bits */
|
||||
config->cfg &= ~(BIT(13) | BIT(14));
|
||||
config->cfg &= ~(TRCCONFIGR_QE_W_COUNTS | TRCCONFIGR_QE_WO_COUNTS);
|
||||
/*
|
||||
* if supported, Q elements with instruction counts are enabled.
|
||||
* Always set the low bit for any requested mode. Valid combos are
|
||||
* 0b00, 0b01 and 0b11.
|
||||
*/
|
||||
if (mode && drvdata->q_support)
|
||||
config->cfg |= BIT(13);
|
||||
config->cfg |= TRCCONFIGR_QE_W_COUNTS;
|
||||
/*
|
||||
* if supported, Q elements with and without instruction
|
||||
* counts are enabled
|
||||
*/
|
||||
if ((mode & BIT(1)) && (drvdata->q_support & BIT(1)))
|
||||
config->cfg |= BIT(14);
|
||||
config->cfg |= TRCCONFIGR_QE_WO_COUNTS;
|
||||
|
||||
/* bit[11], AMBA Trace Bus (ATB) trigger enable bit */
|
||||
if ((config->mode & ETM_MODE_ATB_TRIGGER) &&
|
||||
(drvdata->atbtrig == true))
|
||||
config->eventctrl1 |= BIT(11);
|
||||
config->eventctrl1 |= TRCEVENTCTL1R_ATB;
|
||||
else
|
||||
config->eventctrl1 &= ~BIT(11);
|
||||
config->eventctrl1 &= ~TRCEVENTCTL1R_ATB;
|
||||
|
||||
/* bit[12], Low-power state behavior override bit */
|
||||
if ((config->mode & ETM_MODE_LPOVERRIDE) &&
|
||||
(drvdata->lpoverride == true))
|
||||
config->eventctrl1 |= BIT(12);
|
||||
config->eventctrl1 |= TRCEVENTCTL1R_LPOVERRIDE;
|
||||
else
|
||||
config->eventctrl1 &= ~BIT(12);
|
||||
config->eventctrl1 &= ~TRCEVENTCTL1R_LPOVERRIDE;
|
||||
|
||||
/* bit[8], Instruction stall bit */
|
||||
if ((config->mode & ETM_MODE_ISTALL_EN) && (drvdata->stallctl == true))
|
||||
config->stall_ctrl |= BIT(8);
|
||||
config->stall_ctrl |= TRCSTALLCTLR_ISTALL;
|
||||
else
|
||||
config->stall_ctrl &= ~BIT(8);
|
||||
config->stall_ctrl &= ~TRCSTALLCTLR_ISTALL;
|
||||
|
||||
/* bit[10], Prioritize instruction trace bit */
|
||||
if (config->mode & ETM_MODE_INSTPRIO)
|
||||
config->stall_ctrl |= BIT(10);
|
||||
config->stall_ctrl |= TRCSTALLCTLR_INSTPRIORITY;
|
||||
else
|
||||
config->stall_ctrl &= ~BIT(10);
|
||||
config->stall_ctrl &= ~TRCSTALLCTLR_INSTPRIORITY;
|
||||
|
||||
/* bit[13], Trace overflow prevention bit */
|
||||
if ((config->mode & ETM_MODE_NOOVERFLOW) &&
|
||||
(drvdata->nooverflow == true))
|
||||
config->stall_ctrl |= BIT(13);
|
||||
config->stall_ctrl |= TRCSTALLCTLR_NOOVERFLOW;
|
||||
else
|
||||
config->stall_ctrl &= ~BIT(13);
|
||||
config->stall_ctrl &= ~TRCSTALLCTLR_NOOVERFLOW;
|
||||
|
||||
/* bit[9] Start/stop logic control bit */
|
||||
if (config->mode & ETM_MODE_VIEWINST_STARTSTOP)
|
||||
config->vinst_ctrl |= BIT(9);
|
||||
config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
|
||||
else
|
||||
config->vinst_ctrl &= ~BIT(9);
|
||||
config->vinst_ctrl &= ~TRCVICTLR_SSSTATUS;
|
||||
|
||||
/* bit[10], Whether a trace unit must trace a Reset exception */
|
||||
if (config->mode & ETM_MODE_TRACE_RESET)
|
||||
config->vinst_ctrl |= BIT(10);
|
||||
config->vinst_ctrl |= TRCVICTLR_TRCRESET;
|
||||
else
|
||||
config->vinst_ctrl &= ~BIT(10);
|
||||
config->vinst_ctrl &= ~TRCVICTLR_TRCRESET;
|
||||
|
||||
/* bit[11], Whether a trace unit must trace a system error exception */
|
||||
if ((config->mode & ETM_MODE_TRACE_ERR) &&
|
||||
(drvdata->trc_error == true))
|
||||
config->vinst_ctrl |= BIT(11);
|
||||
config->vinst_ctrl |= TRCVICTLR_TRCERR;
|
||||
else
|
||||
config->vinst_ctrl &= ~BIT(11);
|
||||
config->vinst_ctrl &= ~TRCVICTLR_TRCERR;
|
||||
|
||||
if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
|
||||
etm4_config_trace_mode(config);
|
||||
|
@ -534,7 +534,7 @@ static ssize_t event_instren_show(struct device *dev,
|
|||
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
|
||||
struct etmv4_config *config = &drvdata->config;
|
||||
|
||||
val = BMVAL(config->eventctrl1, 0, 3);
|
||||
val = FIELD_GET(TRCEVENTCTL1R_INSTEN_MASK, config->eventctrl1);
|
||||
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
|
||||
}
|
||||
|
||||
|
@ -551,23 +551,28 @@ static ssize_t event_instren_store(struct device *dev,
|
|||
|
||||
spin_lock(&drvdata->spinlock);
|
||||
/* start by clearing all instruction event enable bits */
|
||||
config->eventctrl1 &= ~(BIT(0) | BIT(1) | BIT(2) | BIT(3));
|
||||
config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK;
|
||||
switch (drvdata->nr_event) {
|
||||
case 0x0:
|
||||
/* generate Event element for event 1 */
|
||||
config->eventctrl1 |= val & BIT(1);
|
||||
config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_1;
|
||||
break;
|
||||
case 0x1:
|
||||
/* generate Event element for event 1 and 2 */
|
||||
config->eventctrl1 |= val & (BIT(0) | BIT(1));
|
||||
config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1);
|
||||
break;
|
||||
case 0x2:
|
||||
/* generate Event element for event 1, 2 and 3 */
|
||||
config->eventctrl1 |= val & (BIT(0) | BIT(1) | BIT(2));
|
||||
config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 |
|
||||
TRCEVENTCTL1R_INSTEN_1 |
|
||||
TRCEVENTCTL1R_INSTEN_2);
|
||||
break;
|
||||
case 0x3:
|
||||
/* generate Event element for all 4 events */
|
||||
config->eventctrl1 |= val & 0xF;
|
||||
config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 |
|
||||
TRCEVENTCTL1R_INSTEN_1 |
|
||||
TRCEVENTCTL1R_INSTEN_2 |
|
||||
TRCEVENTCTL1R_INSTEN_3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -702,10 +707,10 @@ static ssize_t bb_ctrl_store(struct device *dev,
|
|||
* individual range comparators. If include then at least 1
|
||||
* range must be selected.
|
||||
*/
|
||||
if ((val & BIT(8)) && (BMVAL(val, 0, 7) == 0))
|
||||
if ((val & TRCBBCTLR_MODE) && (FIELD_GET(TRCBBCTLR_RANGE_MASK, val) == 0))
|
||||
return -EINVAL;
|
||||
|
||||
config->bb_ctrl = val & GENMASK(8, 0);
|
||||
config->bb_ctrl = val & (TRCBBCTLR_MODE | TRCBBCTLR_RANGE_MASK);
|
||||
return size;
|
||||
}
|
||||
static DEVICE_ATTR_RW(bb_ctrl);
|
||||
|
@ -718,7 +723,7 @@ static ssize_t event_vinst_show(struct device *dev,
|
|||
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
|
||||
struct etmv4_config *config = &drvdata->config;
|
||||
|
||||
val = config->vinst_ctrl & ETMv4_EVENT_MASK;
|
||||
val = FIELD_GET(TRCVICTLR_EVENT_MASK, config->vinst_ctrl);
|
||||
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
|
||||
}
|
||||
|
||||
|
@ -734,9 +739,9 @@ static ssize_t event_vinst_store(struct device *dev,
|
|||
return -EINVAL;
|
||||
|
||||
spin_lock(&drvdata->spinlock);
|
||||
val &= ETMv4_EVENT_MASK;
|
||||
config->vinst_ctrl &= ~ETMv4_EVENT_MASK;
|
||||
config->vinst_ctrl |= val;
|
||||
val &= TRCVICTLR_EVENT_MASK >> __bf_shf(TRCVICTLR_EVENT_MASK);
|
||||
config->vinst_ctrl &= ~TRCVICTLR_EVENT_MASK;
|
||||
config->vinst_ctrl |= FIELD_PREP(TRCVICTLR_EVENT_MASK, val);
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return size;
|
||||
}
|
||||
|
@ -750,7 +755,7 @@ static ssize_t s_exlevel_vinst_show(struct device *dev,
|
|||
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
|
||||
struct etmv4_config *config = &drvdata->config;
|
||||
|
||||
val = (config->vinst_ctrl & TRCVICTLR_EXLEVEL_S_MASK) >> TRCVICTLR_EXLEVEL_S_SHIFT;
|
||||
val = FIELD_GET(TRCVICTLR_EXLEVEL_S_MASK, config->vinst_ctrl);
|
||||
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
|
||||
}
|
||||
|
||||
|
@ -767,10 +772,10 @@ static ssize_t s_exlevel_vinst_store(struct device *dev,
|
|||
|
||||
spin_lock(&drvdata->spinlock);
|
||||
/* clear all EXLEVEL_S bits */
|
||||
config->vinst_ctrl &= ~(TRCVICTLR_EXLEVEL_S_MASK);
|
||||
config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_S_MASK;
|
||||
/* enable instruction tracing for corresponding exception level */
|
||||
val &= drvdata->s_ex_level;
|
||||
config->vinst_ctrl |= (val << TRCVICTLR_EXLEVEL_S_SHIFT);
|
||||
config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_S_MASK);
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return size;
|
||||
}
|
||||
|
@ -785,7 +790,7 @@ static ssize_t ns_exlevel_vinst_show(struct device *dev,
|
|||
struct etmv4_config *config = &drvdata->config;
|
||||
|
||||
/* EXLEVEL_NS, bits[23:20] */
|
||||
val = (config->vinst_ctrl & TRCVICTLR_EXLEVEL_NS_MASK) >> TRCVICTLR_EXLEVEL_NS_SHIFT;
|
||||
val = FIELD_GET(TRCVICTLR_EXLEVEL_NS_MASK, config->vinst_ctrl);
|
||||
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
|
||||
}
|
||||
|
||||
|
@ -802,10 +807,10 @@ static ssize_t ns_exlevel_vinst_store(struct device *dev,
|
|||
|
||||
spin_lock(&drvdata->spinlock);
|
||||
/* clear EXLEVEL_NS bits */
|
||||
config->vinst_ctrl &= ~(TRCVICTLR_EXLEVEL_NS_MASK);
|
||||
config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_NS_MASK;
|
||||
/* enable instruction tracing for corresponding exception level */
|
||||
val &= drvdata->ns_ex_level;
|
||||
config->vinst_ctrl |= (val << TRCVICTLR_EXLEVEL_NS_SHIFT);
|
||||
config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_NS_MASK);
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return size;
|
||||
}
|
||||
|
@ -858,11 +863,11 @@ static ssize_t addr_instdatatype_show(struct device *dev,
|
|||
|
||||
spin_lock(&drvdata->spinlock);
|
||||
idx = config->addr_idx;
|
||||
val = BMVAL(config->addr_acc[idx], 0, 1);
|
||||
val = FIELD_GET(TRCACATRn_TYPE_MASK, config->addr_acc[idx]);
|
||||
len = scnprintf(buf, PAGE_SIZE, "%s\n",
|
||||
val == ETM_INSTR_ADDR ? "instr" :
|
||||
(val == ETM_DATA_LOAD_ADDR ? "data_load" :
|
||||
(val == ETM_DATA_STORE_ADDR ? "data_store" :
|
||||
val == TRCACATRn_TYPE_ADDR ? "instr" :
|
||||
(val == TRCACATRn_TYPE_DATA_LOAD_ADDR ? "data_load" :
|
||||
(val == TRCACATRn_TYPE_DATA_STORE_ADDR ? "data_store" :
|
||||
"data_load_store")));
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return len;
|
||||
|
@ -886,7 +891,7 @@ static ssize_t addr_instdatatype_store(struct device *dev,
|
|||
idx = config->addr_idx;
|
||||
if (!strcmp(str, "instr"))
|
||||
/* TYPE, bits[1:0] */
|
||||
config->addr_acc[idx] &= ~(BIT(0) | BIT(1));
|
||||
config->addr_acc[idx] &= ~TRCACATRn_TYPE_MASK;
|
||||
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return size;
|
||||
|
@ -1144,7 +1149,7 @@ static ssize_t addr_ctxtype_show(struct device *dev,
|
|||
spin_lock(&drvdata->spinlock);
|
||||
idx = config->addr_idx;
|
||||
/* CONTEXTTYPE, bits[3:2] */
|
||||
val = BMVAL(config->addr_acc[idx], 2, 3);
|
||||
val = FIELD_GET(TRCACATRn_CONTEXTTYPE_MASK, config->addr_acc[idx]);
|
||||
len = scnprintf(buf, PAGE_SIZE, "%s\n", val == ETM_CTX_NONE ? "none" :
|
||||
(val == ETM_CTX_CTXID ? "ctxid" :
|
||||
(val == ETM_CTX_VMID ? "vmid" : "all")));
|
||||
|
@ -1170,18 +1175,18 @@ static ssize_t addr_ctxtype_store(struct device *dev,
|
|||
idx = config->addr_idx;
|
||||
if (!strcmp(str, "none"))
|
||||
/* start by clearing context type bits */
|
||||
config->addr_acc[idx] &= ~(BIT(2) | BIT(3));
|
||||
config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_MASK;
|
||||
else if (!strcmp(str, "ctxid")) {
|
||||
/* 0b01 The trace unit performs a Context ID */
|
||||
if (drvdata->numcidc) {
|
||||
config->addr_acc[idx] |= BIT(2);
|
||||
config->addr_acc[idx] &= ~BIT(3);
|
||||
config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_CTXID;
|
||||
config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_VMID;
|
||||
}
|
||||
} else if (!strcmp(str, "vmid")) {
|
||||
/* 0b10 The trace unit performs a VMID */
|
||||
if (drvdata->numvmidc) {
|
||||
config->addr_acc[idx] &= ~BIT(2);
|
||||
config->addr_acc[idx] |= BIT(3);
|
||||
config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_CTXID;
|
||||
config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
|
||||
}
|
||||
} else if (!strcmp(str, "all")) {
|
||||
/*
|
||||
|
@ -1189,9 +1194,9 @@ static ssize_t addr_ctxtype_store(struct device *dev,
|
|||
* comparison and a VMID
|
||||
*/
|
||||
if (drvdata->numcidc)
|
||||
config->addr_acc[idx] |= BIT(2);
|
||||
config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_CTXID;
|
||||
if (drvdata->numvmidc)
|
||||
config->addr_acc[idx] |= BIT(3);
|
||||
config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
|
||||
}
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return size;
|
||||
|
@ -1210,7 +1215,7 @@ static ssize_t addr_context_show(struct device *dev,
|
|||
spin_lock(&drvdata->spinlock);
|
||||
idx = config->addr_idx;
|
||||
/* context ID comparator bits[6:4] */
|
||||
val = BMVAL(config->addr_acc[idx], 4, 6);
|
||||
val = FIELD_GET(TRCACATRn_CONTEXT_MASK, config->addr_acc[idx]);
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
|
||||
}
|
||||
|
@ -1235,8 +1240,8 @@ static ssize_t addr_context_store(struct device *dev,
|
|||
spin_lock(&drvdata->spinlock);
|
||||
idx = config->addr_idx;
|
||||
/* clear context ID comparator bits[6:4] */
|
||||
config->addr_acc[idx] &= ~(BIT(4) | BIT(5) | BIT(6));
|
||||
config->addr_acc[idx] |= (val << 4);
|
||||
config->addr_acc[idx] &= ~TRCACATRn_CONTEXT_MASK;
|
||||
config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_CONTEXT_MASK);
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return size;
|
||||
}
|
||||
|
@ -1253,7 +1258,7 @@ static ssize_t addr_exlevel_s_ns_show(struct device *dev,
|
|||
|
||||
spin_lock(&drvdata->spinlock);
|
||||
idx = config->addr_idx;
|
||||
val = BMVAL(config->addr_acc[idx], 8, 14);
|
||||
val = FIELD_GET(TRCACATRn_EXLEVEL_MASK, config->addr_acc[idx]);
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
|
||||
}
|
||||
|
@ -1270,14 +1275,14 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
|
|||
if (kstrtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val & ~((GENMASK(14, 8) >> 8)))
|
||||
if (val & ~(TRCACATRn_EXLEVEL_MASK >> __bf_shf(TRCACATRn_EXLEVEL_MASK)))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&drvdata->spinlock);
|
||||
idx = config->addr_idx;
|
||||
/* clear Exlevel_ns & Exlevel_s bits[14:12, 11:8], bit[15] is res0 */
|
||||
config->addr_acc[idx] &= ~(GENMASK(14, 8));
|
||||
config->addr_acc[idx] |= (val << 8);
|
||||
config->addr_acc[idx] &= ~TRCACATRn_EXLEVEL_MASK;
|
||||
config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_EXLEVEL_MASK);
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return size;
|
||||
}
|
||||
|
@ -1721,8 +1726,11 @@ static ssize_t res_ctrl_store(struct device *dev,
|
|||
/* For odd idx pair inversal bit is RES0 */
|
||||
if (idx % 2 != 0)
|
||||
/* PAIRINV, bit[21] */
|
||||
val &= ~BIT(21);
|
||||
config->res_ctrl[idx] = val & GENMASK(21, 0);
|
||||
val &= ~TRCRSCTLRn_PAIRINV;
|
||||
config->res_ctrl[idx] = val & (TRCRSCTLRn_PAIRINV |
|
||||
TRCRSCTLRn_INV |
|
||||
TRCRSCTLRn_GROUP_MASK |
|
||||
TRCRSCTLRn_SELECT_MASK);
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return size;
|
||||
}
|
||||
|
@ -1787,9 +1795,9 @@ static ssize_t sshot_ctrl_store(struct device *dev,
|
|||
|
||||
spin_lock(&drvdata->spinlock);
|
||||
idx = config->ss_idx;
|
||||
config->ss_ctrl[idx] = val & GENMASK(24, 0);
|
||||
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] &= ~BIT(31);
|
||||
config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return size;
|
||||
}
|
||||
|
@ -1837,9 +1845,9 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev,
|
|||
|
||||
spin_lock(&drvdata->spinlock);
|
||||
idx = config->ss_idx;
|
||||
config->ss_pe_cmp[idx] = val & GENMASK(7, 0);
|
||||
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] &= ~BIT(31);
|
||||
config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return size;
|
||||
}
|
||||
|
|
|
@ -130,6 +130,104 @@
|
|||
|
||||
#define TRCRSR_TA BIT(12)
|
||||
|
||||
/*
|
||||
* Bit positions of registers that are defined above, in the sysreg.h style
|
||||
* of _MASK for multi bit fields and BIT() for single bits.
|
||||
*/
|
||||
#define TRCIDR0_INSTP0_MASK GENMASK(2, 1)
|
||||
#define TRCIDR0_TRCBB BIT(5)
|
||||
#define TRCIDR0_TRCCOND BIT(6)
|
||||
#define TRCIDR0_TRCCCI BIT(7)
|
||||
#define TRCIDR0_RETSTACK BIT(9)
|
||||
#define TRCIDR0_NUMEVENT_MASK GENMASK(11, 10)
|
||||
#define TRCIDR0_QSUPP_MASK GENMASK(16, 15)
|
||||
#define TRCIDR0_TSSIZE_MASK GENMASK(28, 24)
|
||||
|
||||
#define TRCIDR2_CIDSIZE_MASK GENMASK(9, 5)
|
||||
#define TRCIDR2_VMIDSIZE_MASK GENMASK(14, 10)
|
||||
#define TRCIDR2_CCSIZE_MASK GENMASK(28, 25)
|
||||
|
||||
#define TRCIDR3_CCITMIN_MASK GENMASK(11, 0)
|
||||
#define TRCIDR3_EXLEVEL_S_MASK GENMASK(19, 16)
|
||||
#define TRCIDR3_EXLEVEL_NS_MASK GENMASK(23, 20)
|
||||
#define TRCIDR3_TRCERR BIT(24)
|
||||
#define TRCIDR3_SYNCPR BIT(25)
|
||||
#define TRCIDR3_STALLCTL BIT(26)
|
||||
#define TRCIDR3_SYSSTALL BIT(27)
|
||||
#define TRCIDR3_NUMPROC_LO_MASK GENMASK(30, 28)
|
||||
#define TRCIDR3_NUMPROC_HI_MASK GENMASK(13, 12)
|
||||
#define TRCIDR3_NOOVERFLOW BIT(31)
|
||||
|
||||
#define TRCIDR4_NUMACPAIRS_MASK GENMASK(3, 0)
|
||||
#define TRCIDR4_NUMPC_MASK GENMASK(15, 12)
|
||||
#define TRCIDR4_NUMRSPAIR_MASK GENMASK(19, 16)
|
||||
#define TRCIDR4_NUMSSCC_MASK GENMASK(23, 20)
|
||||
#define TRCIDR4_NUMCIDC_MASK GENMASK(27, 24)
|
||||
#define TRCIDR4_NUMVMIDC_MASK GENMASK(31, 28)
|
||||
|
||||
#define TRCIDR5_NUMEXTIN_MASK GENMASK(8, 0)
|
||||
#define TRCIDR5_TRACEIDSIZE_MASK GENMASK(21, 16)
|
||||
#define TRCIDR5_ATBTRIG BIT(22)
|
||||
#define TRCIDR5_LPOVERRIDE BIT(23)
|
||||
#define TRCIDR5_NUMSEQSTATE_MASK GENMASK(27, 25)
|
||||
#define TRCIDR5_NUMCNTR_MASK GENMASK(30, 28)
|
||||
|
||||
#define TRCCONFIGR_INSTP0_LOAD BIT(1)
|
||||
#define TRCCONFIGR_INSTP0_STORE BIT(2)
|
||||
#define TRCCONFIGR_INSTP0_LOAD_STORE (TRCCONFIGR_INSTP0_LOAD | TRCCONFIGR_INSTP0_STORE)
|
||||
#define TRCCONFIGR_BB BIT(3)
|
||||
#define TRCCONFIGR_CCI BIT(4)
|
||||
#define TRCCONFIGR_CID BIT(6)
|
||||
#define TRCCONFIGR_VMID BIT(7)
|
||||
#define TRCCONFIGR_COND_MASK GENMASK(10, 8)
|
||||
#define TRCCONFIGR_TS BIT(11)
|
||||
#define TRCCONFIGR_RS BIT(12)
|
||||
#define TRCCONFIGR_QE_W_COUNTS BIT(13)
|
||||
#define TRCCONFIGR_QE_WO_COUNTS BIT(14)
|
||||
#define TRCCONFIGR_VMIDOPT BIT(15)
|
||||
#define TRCCONFIGR_DA BIT(16)
|
||||
#define TRCCONFIGR_DV BIT(17)
|
||||
|
||||
#define TRCEVENTCTL1R_INSTEN_MASK GENMASK(3, 0)
|
||||
#define TRCEVENTCTL1R_INSTEN_0 BIT(0)
|
||||
#define TRCEVENTCTL1R_INSTEN_1 BIT(1)
|
||||
#define TRCEVENTCTL1R_INSTEN_2 BIT(2)
|
||||
#define TRCEVENTCTL1R_INSTEN_3 BIT(3)
|
||||
#define TRCEVENTCTL1R_ATB BIT(11)
|
||||
#define TRCEVENTCTL1R_LPOVERRIDE BIT(12)
|
||||
|
||||
#define TRCSTALLCTLR_ISTALL BIT(8)
|
||||
#define TRCSTALLCTLR_INSTPRIORITY BIT(10)
|
||||
#define TRCSTALLCTLR_NOOVERFLOW BIT(13)
|
||||
|
||||
#define TRCVICTLR_EVENT_MASK GENMASK(7, 0)
|
||||
#define TRCVICTLR_SSSTATUS BIT(9)
|
||||
#define TRCVICTLR_TRCRESET BIT(10)
|
||||
#define TRCVICTLR_TRCERR BIT(11)
|
||||
#define TRCVICTLR_EXLEVEL_MASK GENMASK(22, 16)
|
||||
#define TRCVICTLR_EXLEVEL_S_MASK GENMASK(19, 16)
|
||||
#define TRCVICTLR_EXLEVEL_NS_MASK GENMASK(22, 20)
|
||||
|
||||
#define TRCACATRn_TYPE_MASK GENMASK(1, 0)
|
||||
#define TRCACATRn_CONTEXTTYPE_MASK GENMASK(3, 2)
|
||||
#define TRCACATRn_CONTEXTTYPE_CTXID BIT(2)
|
||||
#define TRCACATRn_CONTEXTTYPE_VMID BIT(3)
|
||||
#define TRCACATRn_CONTEXT_MASK GENMASK(6, 4)
|
||||
#define TRCACATRn_EXLEVEL_MASK GENMASK(14, 8)
|
||||
|
||||
#define TRCSSCSRn_STATUS BIT(31)
|
||||
#define TRCSSCCRn_SAC_ARC_RST_MASK GENMASK(24, 0)
|
||||
|
||||
#define TRCSSPCICRn_PC_MASK GENMASK(7, 0)
|
||||
|
||||
#define TRCBBCTLR_MODE BIT(8)
|
||||
#define TRCBBCTLR_RANGE_MASK GENMASK(7, 0)
|
||||
|
||||
#define TRCRSCTLRn_PAIRINV BIT(21)
|
||||
#define TRCRSCTLRn_INV BIT(20)
|
||||
#define TRCRSCTLRn_GROUP_MASK GENMASK(19, 16)
|
||||
#define TRCRSCTLRn_SELECT_MASK GENMASK(15, 0)
|
||||
|
||||
/*
|
||||
* System instructions to access ETM registers.
|
||||
* See ETMv4.4 spec ARM IHI0064F section 4.3.6 System instructions
|
||||
|
@ -630,23 +728,9 @@
|
|||
#define ETM_EXLEVEL_NS_OS BIT(5) /* NonSecure EL1 */
|
||||
#define ETM_EXLEVEL_NS_HYP BIT(6) /* NonSecure EL2 */
|
||||
|
||||
#define ETM_EXLEVEL_MASK (GENMASK(6, 0))
|
||||
#define ETM_EXLEVEL_S_MASK (GENMASK(3, 0))
|
||||
#define ETM_EXLEVEL_NS_MASK (GENMASK(6, 4))
|
||||
|
||||
/* access level controls in TRCACATRn */
|
||||
#define TRCACATR_EXLEVEL_SHIFT 8
|
||||
|
||||
/* access level control in TRCVICTLR */
|
||||
#define TRCVICTLR_EXLEVEL_SHIFT 16
|
||||
#define TRCVICTLR_EXLEVEL_S_SHIFT 16
|
||||
#define TRCVICTLR_EXLEVEL_NS_SHIFT 20
|
||||
|
||||
/* secure / non secure masks - TRCVICTLR, IDR3 */
|
||||
#define TRCVICTLR_EXLEVEL_MASK (ETM_EXLEVEL_MASK << TRCVICTLR_EXLEVEL_SHIFT)
|
||||
#define TRCVICTLR_EXLEVEL_S_MASK (ETM_EXLEVEL_S_MASK << TRCVICTLR_EXLEVEL_SHIFT)
|
||||
#define TRCVICTLR_EXLEVEL_NS_MASK (ETM_EXLEVEL_NS_MASK << TRCVICTLR_EXLEVEL_SHIFT)
|
||||
|
||||
#define ETM_TRCIDR1_ARCH_MAJOR_SHIFT 8
|
||||
#define ETM_TRCIDR1_ARCH_MAJOR_MASK (0xfU << ETM_TRCIDR1_ARCH_MAJOR_SHIFT)
|
||||
#define ETM_TRCIDR1_ARCH_MAJOR(x) \
|
||||
|
@ -986,10 +1070,10 @@ struct etmv4_drvdata {
|
|||
|
||||
/* Address comparator access types */
|
||||
enum etm_addr_acctype {
|
||||
ETM_INSTR_ADDR,
|
||||
ETM_DATA_LOAD_ADDR,
|
||||
ETM_DATA_STORE_ADDR,
|
||||
ETM_DATA_LOAD_STORE_ADDR,
|
||||
TRCACATRn_TYPE_ADDR,
|
||||
TRCACATRn_TYPE_DATA_LOAD_ADDR,
|
||||
TRCACATRn_TYPE_DATA_STORE_ADDR,
|
||||
TRCACATRn_TYPE_DATA_LOAD_STORE_ADDR,
|
||||
};
|
||||
|
||||
/* Address comparator context types */
|
||||
|
|
Loading…
Reference in New Issue