in coresight/coresight-etm4x-sysfs.c [291:438]
static ssize_t mode_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val, mode;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
spin_lock(&drvdata->spinlock);
config->mode = val & ETMv4_MODE_ALL;
if (drvdata->instrp0 == true) {
/* start by clearing instruction P0 field */
config->cfg &= ~(BIT(1) | BIT(2));
if (config->mode & ETM_MODE_LOAD)
/* 0b01 Trace load instructions as P0 instructions */
config->cfg |= BIT(1);
if (config->mode & ETM_MODE_STORE)
/* 0b10 Trace store instructions as P0 instructions */
config->cfg |= BIT(2);
if (config->mode & ETM_MODE_LOAD_STORE)
/*
* 0b11 Trace load and store instructions
* as P0 instructions
*/
config->cfg |= BIT(1) | BIT(2);
}
/* bit[3], Branch broadcast mode */
if ((config->mode & ETM_MODE_BB) && (drvdata->trcbb == true))
config->cfg |= BIT(3);
else
config->cfg &= ~BIT(3);
/* bit[4], Cycle counting instruction trace bit */
if ((config->mode & ETMv4_MODE_CYCACC) &&
(drvdata->trccci == true))
config->cfg |= BIT(4);
else
config->cfg &= ~BIT(4);
/* bit[6], Context ID tracing bit */
if ((config->mode & ETMv4_MODE_CTXID) && (drvdata->ctxid_size))
config->cfg |= BIT(6);
else
config->cfg &= ~BIT(6);
if ((config->mode & ETM_MODE_VMID) && (drvdata->vmid_size))
config->cfg |= BIT(7);
else
config->cfg &= ~BIT(7);
/* 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;
}
/* bit[11], Global timestamp tracing bit */
if ((config->mode & ETMv4_MODE_TIMESTAMP) && (drvdata->ts_size))
config->cfg |= BIT(11);
else
config->cfg &= ~BIT(11);
/* bit[12], Return stack enable bit */
if ((config->mode & ETM_MODE_RETURNSTACK) &&
(drvdata->retstack == true))
config->cfg |= BIT(12);
else
config->cfg &= ~BIT(12);
/* bits[14:13], Q element enable field */
mode = ETM_MODE_QELEM(config->mode);
/* start by clearing QE bits */
config->cfg &= ~(BIT(13) | BIT(14));
/* if supported, Q elements with instruction counts are enabled */
if ((mode & BIT(0)) && (drvdata->q_support & BIT(0)))
config->cfg |= BIT(13);
/*
* if supported, Q elements with and without instruction
* counts are enabled
*/
if ((mode & BIT(1)) && (drvdata->q_support & BIT(1)))
config->cfg |= BIT(14);
/* bit[11], AMBA Trace Bus (ATB) trigger enable bit */
if ((config->mode & ETM_MODE_ATB_TRIGGER) &&
(drvdata->atbtrig == true))
config->eventctrl1 |= BIT(11);
else
config->eventctrl1 &= ~BIT(11);
/* bit[12], Low-power state behavior override bit */
if ((config->mode & ETM_MODE_LPOVERRIDE) &&
(drvdata->lpoverride == true))
config->eventctrl1 |= BIT(12);
else
config->eventctrl1 &= ~BIT(12);
/* bit[8], Instruction stall bit */
if ((config->mode & ETM_MODE_ISTALL_EN) && (drvdata->stallctl == true))
config->stall_ctrl |= BIT(8);
else
config->stall_ctrl &= ~BIT(8);
/* bit[10], Prioritize instruction trace bit */
if (config->mode & ETM_MODE_INSTPRIO)
config->stall_ctrl |= BIT(10);
else
config->stall_ctrl &= ~BIT(10);
/* bit[13], Trace overflow prevention bit */
if ((config->mode & ETM_MODE_NOOVERFLOW) &&
(drvdata->nooverflow == true))
config->stall_ctrl |= BIT(13);
else
config->stall_ctrl &= ~BIT(13);
/* bit[9] Start/stop logic control bit */
if (config->mode & ETM_MODE_VIEWINST_STARTSTOP)
config->vinst_ctrl |= BIT(9);
else
config->vinst_ctrl &= ~BIT(9);
/* bit[10], Whether a trace unit must trace a Reset exception */
if (config->mode & ETM_MODE_TRACE_RESET)
config->vinst_ctrl |= BIT(10);
else
config->vinst_ctrl &= ~BIT(10);
/* 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);
else
config->vinst_ctrl &= ~BIT(11);
if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
etm4_config_trace_mode(config);
spin_unlock(&drvdata->spinlock);
return size;
}