brintos

brintos / linux-shallow public Read only

0
0
Text · 69.6 KiB · a9f1962 Raw
2604 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright(C) 2015 Linaro Limited. All rights reserved.4 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>5 */6 7#include <linux/pid_namespace.h>8#include <linux/pm_runtime.h>9#include <linux/sysfs.h>10#include "coresight-etm4x.h"11#include "coresight-priv.h"12#include "coresight-syscfg.h"13 14static int etm4_set_mode_exclude(struct etmv4_drvdata *drvdata, bool exclude)15{16	u8 idx;17	struct etmv4_config *config = &drvdata->config;18 19	idx = config->addr_idx;20 21	/*22	 * TRCACATRn.TYPE bit[1:0]: type of comparison23	 * the trace unit performs24	 */25	if (FIELD_GET(TRCACATRn_TYPE_MASK, config->addr_acc[idx]) == TRCACATRn_TYPE_ADDR) {26		if (idx % 2 != 0)27			return -EINVAL;28 29		/*30		 * We are performing instruction address comparison. Set the31		 * relevant bit of ViewInst Include/Exclude Control register32		 * for corresponding address comparator pair.33		 */34		if (config->addr_type[idx] != ETM_ADDR_TYPE_RANGE ||35		    config->addr_type[idx + 1] != ETM_ADDR_TYPE_RANGE)36			return -EINVAL;37 38		if (exclude == true) {39			/*40			 * Set exclude bit and unset the include bit41			 * corresponding to comparator pair42			 */43			config->viiectlr |= BIT(idx / 2 + 16);44			config->viiectlr &= ~BIT(idx / 2);45		} else {46			/*47			 * Set include bit and unset exclude bit48			 * corresponding to comparator pair49			 */50			config->viiectlr |= BIT(idx / 2);51			config->viiectlr &= ~BIT(idx / 2 + 16);52		}53	}54	return 0;55}56 57static ssize_t nr_pe_cmp_show(struct device *dev,58			      struct device_attribute *attr,59			      char *buf)60{61	unsigned long val;62	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);63 64	val = drvdata->nr_pe_cmp;65	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);66}67static DEVICE_ATTR_RO(nr_pe_cmp);68 69static ssize_t nr_addr_cmp_show(struct device *dev,70				struct device_attribute *attr,71				char *buf)72{73	unsigned long val;74	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);75 76	val = drvdata->nr_addr_cmp;77	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);78}79static DEVICE_ATTR_RO(nr_addr_cmp);80 81static ssize_t nr_cntr_show(struct device *dev,82			    struct device_attribute *attr,83			    char *buf)84{85	unsigned long val;86	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);87 88	val = drvdata->nr_cntr;89	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);90}91static DEVICE_ATTR_RO(nr_cntr);92 93static ssize_t nr_ext_inp_show(struct device *dev,94			       struct device_attribute *attr,95			       char *buf)96{97	unsigned long val;98	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);99 100	val = drvdata->nr_ext_inp;101	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);102}103static DEVICE_ATTR_RO(nr_ext_inp);104 105static ssize_t numcidc_show(struct device *dev,106			    struct device_attribute *attr,107			    char *buf)108{109	unsigned long val;110	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);111 112	val = drvdata->numcidc;113	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);114}115static DEVICE_ATTR_RO(numcidc);116 117static ssize_t numvmidc_show(struct device *dev,118			     struct device_attribute *attr,119			     char *buf)120{121	unsigned long val;122	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);123 124	val = drvdata->numvmidc;125	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);126}127static DEVICE_ATTR_RO(numvmidc);128 129static ssize_t nrseqstate_show(struct device *dev,130			       struct device_attribute *attr,131			       char *buf)132{133	unsigned long val;134	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);135 136	val = drvdata->nrseqstate;137	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);138}139static DEVICE_ATTR_RO(nrseqstate);140 141static ssize_t nr_resource_show(struct device *dev,142				struct device_attribute *attr,143				char *buf)144{145	unsigned long val;146	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);147 148	val = drvdata->nr_resource;149	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);150}151static DEVICE_ATTR_RO(nr_resource);152 153static ssize_t nr_ss_cmp_show(struct device *dev,154			      struct device_attribute *attr,155			      char *buf)156{157	unsigned long val;158	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);159 160	val = drvdata->nr_ss_cmp;161	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);162}163static DEVICE_ATTR_RO(nr_ss_cmp);164 165static ssize_t reset_store(struct device *dev,166			   struct device_attribute *attr,167			   const char *buf, size_t size)168{169	int i;170	unsigned long val;171	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);172	struct etmv4_config *config = &drvdata->config;173 174	if (kstrtoul(buf, 16, &val))175		return -EINVAL;176 177	spin_lock(&drvdata->spinlock);178	if (val)179		config->mode = 0x0;180 181	/* Disable data tracing: do not trace load and store data transfers */182	config->mode &= ~(ETM_MODE_LOAD | ETM_MODE_STORE);183	config->cfg &= ~(TRCCONFIGR_INSTP0_LOAD | TRCCONFIGR_INSTP0_STORE);184 185	/* Disable data value and data address tracing */186	config->mode &= ~(ETM_MODE_DATA_TRACE_ADDR |187			   ETM_MODE_DATA_TRACE_VAL);188	config->cfg &= ~(TRCCONFIGR_DA | TRCCONFIGR_DV);189 190	/* Disable all events tracing */191	config->eventctrl0 = 0x0;192	config->eventctrl1 = 0x0;193 194	/* Disable timestamp event */195	config->ts_ctrl = 0x0;196 197	/* Disable stalling */198	config->stall_ctrl = 0x0;199 200	/* Reset trace synchronization period  to 2^8 = 256 bytes*/201	if (drvdata->syncpr == false)202		config->syncfreq = 0x8;203 204	/*205	 * Enable ViewInst to trace everything with start-stop logic in206	 * started state. ARM recommends start-stop logic is set before207	 * each trace run.208	 */209	config->vinst_ctrl = FIELD_PREP(TRCVICTLR_EVENT_MASK, 0x01);210	if (drvdata->nr_addr_cmp > 0) {211		config->mode |= ETM_MODE_VIEWINST_STARTSTOP;212		/* SSSTATUS, bit[9] */213		config->vinst_ctrl |= TRCVICTLR_SSSTATUS;214	}215 216	/* No address range filtering for ViewInst */217	config->viiectlr = 0x0;218 219	/* No start-stop filtering for ViewInst */220	config->vissctlr = 0x0;221	config->vipcssctlr = 0x0;222 223	/* Disable seq events */224	for (i = 0; i < drvdata->nrseqstate-1; i++)225		config->seq_ctrl[i] = 0x0;226	config->seq_rst = 0x0;227	config->seq_state = 0x0;228 229	/* Disable external input events */230	config->ext_inp = 0x0;231 232	config->cntr_idx = 0x0;233	for (i = 0; i < drvdata->nr_cntr; i++) {234		config->cntrldvr[i] = 0x0;235		config->cntr_ctrl[i] = 0x0;236		config->cntr_val[i] = 0x0;237	}238 239	config->res_idx = 0x0;240	for (i = 2; i < 2 * drvdata->nr_resource; i++)241		config->res_ctrl[i] = 0x0;242 243	config->ss_idx = 0x0;244	for (i = 0; i < drvdata->nr_ss_cmp; i++) {245		config->ss_ctrl[i] = 0x0;246		config->ss_pe_cmp[i] = 0x0;247	}248 249	config->addr_idx = 0x0;250	for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {251		config->addr_val[i] = 0x0;252		config->addr_acc[i] = 0x0;253		config->addr_type[i] = ETM_ADDR_TYPE_NONE;254	}255 256	config->ctxid_idx = 0x0;257	for (i = 0; i < drvdata->numcidc; i++)258		config->ctxid_pid[i] = 0x0;259 260	config->ctxid_mask0 = 0x0;261	config->ctxid_mask1 = 0x0;262 263	config->vmid_idx = 0x0;264	for (i = 0; i < drvdata->numvmidc; i++)265		config->vmid_val[i] = 0x0;266	config->vmid_mask0 = 0x0;267	config->vmid_mask1 = 0x0;268 269	spin_unlock(&drvdata->spinlock);270 271	/* for sysfs - only release trace id when resetting */272	etm4_release_trace_id(drvdata);273 274	cscfg_csdev_reset_feats(to_coresight_device(dev));275 276	return size;277}278static DEVICE_ATTR_WO(reset);279 280static ssize_t mode_show(struct device *dev,281			 struct device_attribute *attr,282			 char *buf)283{284	unsigned long val;285	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);286	struct etmv4_config *config = &drvdata->config;287 288	val = config->mode;289	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);290}291 292static ssize_t mode_store(struct device *dev,293			  struct device_attribute *attr,294			  const char *buf, size_t size)295{296	unsigned long val, mode;297	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);298	struct etmv4_config *config = &drvdata->config;299 300	if (kstrtoul(buf, 16, &val))301		return -EINVAL;302 303	spin_lock(&drvdata->spinlock);304	config->mode = val & ETMv4_MODE_ALL;305 306	if (drvdata->instrp0 == true) {307		/* start by clearing instruction P0 field */308		config->cfg  &= ~TRCCONFIGR_INSTP0_LOAD_STORE;309		if (config->mode & ETM_MODE_LOAD)310			/* 0b01 Trace load instructions as P0 instructions */311			config->cfg  |= TRCCONFIGR_INSTP0_LOAD;312		if (config->mode & ETM_MODE_STORE)313			/* 0b10 Trace store instructions as P0 instructions */314			config->cfg  |= TRCCONFIGR_INSTP0_STORE;315		if (config->mode & ETM_MODE_LOAD_STORE)316			/*317			 * 0b11 Trace load and store instructions318			 * as P0 instructions319			 */320			config->cfg  |= TRCCONFIGR_INSTP0_LOAD_STORE;321	}322 323	/* bit[3], Branch broadcast mode */324	if ((config->mode & ETM_MODE_BB) && (drvdata->trcbb == true))325		config->cfg |= TRCCONFIGR_BB;326	else327		config->cfg &= ~TRCCONFIGR_BB;328 329	/* bit[4], Cycle counting instruction trace bit */330	if ((config->mode & ETMv4_MODE_CYCACC) &&331		(drvdata->trccci == true))332		config->cfg |= TRCCONFIGR_CCI;333	else334		config->cfg &= ~TRCCONFIGR_CCI;335 336	/* bit[6], Context ID tracing bit */337	if ((config->mode & ETMv4_MODE_CTXID) && (drvdata->ctxid_size))338		config->cfg |= TRCCONFIGR_CID;339	else340		config->cfg &= ~TRCCONFIGR_CID;341 342	if ((config->mode & ETM_MODE_VMID) && (drvdata->vmid_size))343		config->cfg |= TRCCONFIGR_VMID;344	else345		config->cfg &= ~TRCCONFIGR_VMID;346 347	/* bits[10:8], Conditional instruction tracing bit */348	mode = ETM_MODE_COND(config->mode);349	if (drvdata->trccond == true) {350		config->cfg &= ~TRCCONFIGR_COND_MASK;351		config->cfg |= mode << __bf_shf(TRCCONFIGR_COND_MASK);352	}353 354	/* bit[11], Global timestamp tracing bit */355	if ((config->mode & ETMv4_MODE_TIMESTAMP) && (drvdata->ts_size))356		config->cfg |= TRCCONFIGR_TS;357	else358		config->cfg &= ~TRCCONFIGR_TS;359 360	/* bit[12], Return stack enable bit */361	if ((config->mode & ETM_MODE_RETURNSTACK) &&362					(drvdata->retstack == true))363		config->cfg |= TRCCONFIGR_RS;364	else365		config->cfg &= ~TRCCONFIGR_RS;366 367	/* bits[14:13], Q element enable field */368	mode = ETM_MODE_QELEM(config->mode);369	/* start by clearing QE bits */370	config->cfg &= ~(TRCCONFIGR_QE_W_COUNTS | TRCCONFIGR_QE_WO_COUNTS);371	/*372	 * if supported, Q elements with instruction counts are enabled.373	 * Always set the low bit for any requested mode. Valid combos are374	 * 0b00, 0b01 and 0b11.375	 */376	if (mode && drvdata->q_support)377		config->cfg |= TRCCONFIGR_QE_W_COUNTS;378	/*379	 * if supported, Q elements with and without instruction380	 * counts are enabled381	 */382	if ((mode & BIT(1)) && (drvdata->q_support & BIT(1)))383		config->cfg |= TRCCONFIGR_QE_WO_COUNTS;384 385	/* bit[11], AMBA Trace Bus (ATB) trigger enable bit */386	if ((config->mode & ETM_MODE_ATB_TRIGGER) &&387	    (drvdata->atbtrig == true))388		config->eventctrl1 |= TRCEVENTCTL1R_ATB;389	else390		config->eventctrl1 &= ~TRCEVENTCTL1R_ATB;391 392	/* bit[12], Low-power state behavior override bit */393	if ((config->mode & ETM_MODE_LPOVERRIDE) &&394	    (drvdata->lpoverride == true))395		config->eventctrl1 |= TRCEVENTCTL1R_LPOVERRIDE;396	else397		config->eventctrl1 &= ~TRCEVENTCTL1R_LPOVERRIDE;398 399	/* bit[8], Instruction stall bit */400	if ((config->mode & ETM_MODE_ISTALL_EN) && (drvdata->stallctl == true))401		config->stall_ctrl |= TRCSTALLCTLR_ISTALL;402	else403		config->stall_ctrl &= ~TRCSTALLCTLR_ISTALL;404 405	/* bit[10], Prioritize instruction trace bit */406	if (config->mode & ETM_MODE_INSTPRIO)407		config->stall_ctrl |= TRCSTALLCTLR_INSTPRIORITY;408	else409		config->stall_ctrl &= ~TRCSTALLCTLR_INSTPRIORITY;410 411	/* bit[13], Trace overflow prevention bit */412	if ((config->mode & ETM_MODE_NOOVERFLOW) &&413		(drvdata->nooverflow == true))414		config->stall_ctrl |= TRCSTALLCTLR_NOOVERFLOW;415	else416		config->stall_ctrl &= ~TRCSTALLCTLR_NOOVERFLOW;417 418	/* bit[9] Start/stop logic control bit */419	if (config->mode & ETM_MODE_VIEWINST_STARTSTOP)420		config->vinst_ctrl |= TRCVICTLR_SSSTATUS;421	else422		config->vinst_ctrl &= ~TRCVICTLR_SSSTATUS;423 424	/* bit[10], Whether a trace unit must trace a Reset exception */425	if (config->mode & ETM_MODE_TRACE_RESET)426		config->vinst_ctrl |= TRCVICTLR_TRCRESET;427	else428		config->vinst_ctrl &= ~TRCVICTLR_TRCRESET;429 430	/* bit[11], Whether a trace unit must trace a system error exception */431	if ((config->mode & ETM_MODE_TRACE_ERR) &&432		(drvdata->trc_error == true))433		config->vinst_ctrl |= TRCVICTLR_TRCERR;434	else435		config->vinst_ctrl &= ~TRCVICTLR_TRCERR;436 437	if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))438		etm4_config_trace_mode(config);439 440	spin_unlock(&drvdata->spinlock);441 442	return size;443}444static DEVICE_ATTR_RW(mode);445 446static ssize_t pe_show(struct device *dev,447		       struct device_attribute *attr,448		       char *buf)449{450	unsigned long val;451	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);452	struct etmv4_config *config = &drvdata->config;453 454	val = config->pe_sel;455	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);456}457 458static ssize_t pe_store(struct device *dev,459			struct device_attribute *attr,460			const char *buf, size_t size)461{462	unsigned long val;463	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);464	struct etmv4_config *config = &drvdata->config;465 466	if (kstrtoul(buf, 16, &val))467		return -EINVAL;468 469	spin_lock(&drvdata->spinlock);470	if (val > drvdata->nr_pe) {471		spin_unlock(&drvdata->spinlock);472		return -EINVAL;473	}474 475	config->pe_sel = val;476	spin_unlock(&drvdata->spinlock);477	return size;478}479static DEVICE_ATTR_RW(pe);480 481static ssize_t event_show(struct device *dev,482			  struct device_attribute *attr,483			  char *buf)484{485	unsigned long val;486	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);487	struct etmv4_config *config = &drvdata->config;488 489	val = config->eventctrl0;490	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);491}492 493static ssize_t event_store(struct device *dev,494			   struct device_attribute *attr,495			   const char *buf, size_t size)496{497	unsigned long val;498	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);499	struct etmv4_config *config = &drvdata->config;500 501	if (kstrtoul(buf, 16, &val))502		return -EINVAL;503 504	spin_lock(&drvdata->spinlock);505	switch (drvdata->nr_event) {506	case 0x0:507		/* EVENT0, bits[7:0] */508		config->eventctrl0 = val & 0xFF;509		break;510	case 0x1:511		 /* EVENT1, bits[15:8] */512		config->eventctrl0 = val & 0xFFFF;513		break;514	case 0x2:515		/* EVENT2, bits[23:16] */516		config->eventctrl0 = val & 0xFFFFFF;517		break;518	case 0x3:519		/* EVENT3, bits[31:24] */520		config->eventctrl0 = val;521		break;522	default:523		break;524	}525	spin_unlock(&drvdata->spinlock);526	return size;527}528static DEVICE_ATTR_RW(event);529 530static ssize_t event_instren_show(struct device *dev,531				  struct device_attribute *attr,532				  char *buf)533{534	unsigned long val;535	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);536	struct etmv4_config *config = &drvdata->config;537 538	val = FIELD_GET(TRCEVENTCTL1R_INSTEN_MASK, config->eventctrl1);539	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);540}541 542static ssize_t event_instren_store(struct device *dev,543				   struct device_attribute *attr,544				   const char *buf, size_t size)545{546	unsigned long val;547	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);548	struct etmv4_config *config = &drvdata->config;549 550	if (kstrtoul(buf, 16, &val))551		return -EINVAL;552 553	spin_lock(&drvdata->spinlock);554	/* start by clearing all instruction event enable bits */555	config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK;556	switch (drvdata->nr_event) {557	case 0x0:558		/* generate Event element for event 1 */559		config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_1;560		break;561	case 0x1:562		/* generate Event element for event 1 and 2 */563		config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1);564		break;565	case 0x2:566		/* generate Event element for event 1, 2 and 3 */567		config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 |568					     TRCEVENTCTL1R_INSTEN_1 |569					     TRCEVENTCTL1R_INSTEN_2);570		break;571	case 0x3:572		/* generate Event element for all 4 events */573		config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 |574					     TRCEVENTCTL1R_INSTEN_1 |575					     TRCEVENTCTL1R_INSTEN_2 |576					     TRCEVENTCTL1R_INSTEN_3);577		break;578	default:579		break;580	}581	spin_unlock(&drvdata->spinlock);582	return size;583}584static DEVICE_ATTR_RW(event_instren);585 586static ssize_t event_ts_show(struct device *dev,587			     struct device_attribute *attr,588			     char *buf)589{590	unsigned long val;591	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);592	struct etmv4_config *config = &drvdata->config;593 594	val = config->ts_ctrl;595	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);596}597 598static ssize_t event_ts_store(struct device *dev,599			      struct device_attribute *attr,600			      const char *buf, size_t size)601{602	unsigned long val;603	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);604	struct etmv4_config *config = &drvdata->config;605 606	if (kstrtoul(buf, 16, &val))607		return -EINVAL;608	if (!drvdata->ts_size)609		return -EINVAL;610 611	config->ts_ctrl = val & ETMv4_EVENT_MASK;612	return size;613}614static DEVICE_ATTR_RW(event_ts);615 616static ssize_t syncfreq_show(struct device *dev,617			     struct device_attribute *attr,618			     char *buf)619{620	unsigned long val;621	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);622	struct etmv4_config *config = &drvdata->config;623 624	val = config->syncfreq;625	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);626}627 628static ssize_t syncfreq_store(struct device *dev,629			      struct device_attribute *attr,630			      const char *buf, size_t size)631{632	unsigned long val;633	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);634	struct etmv4_config *config = &drvdata->config;635 636	if (kstrtoul(buf, 16, &val))637		return -EINVAL;638	if (drvdata->syncpr == true)639		return -EINVAL;640 641	config->syncfreq = val & ETMv4_SYNC_MASK;642	return size;643}644static DEVICE_ATTR_RW(syncfreq);645 646static ssize_t cyc_threshold_show(struct device *dev,647				  struct device_attribute *attr,648				  char *buf)649{650	unsigned long val;651	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);652	struct etmv4_config *config = &drvdata->config;653 654	val = config->ccctlr;655	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);656}657 658static ssize_t cyc_threshold_store(struct device *dev,659				   struct device_attribute *attr,660				   const char *buf, size_t size)661{662	unsigned long val;663	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);664	struct etmv4_config *config = &drvdata->config;665 666	if (kstrtoul(buf, 16, &val))667		return -EINVAL;668 669	/* mask off max threshold before checking min value */670	val &= ETM_CYC_THRESHOLD_MASK;671	if (val < drvdata->ccitmin)672		return -EINVAL;673 674	config->ccctlr = val;675	return size;676}677static DEVICE_ATTR_RW(cyc_threshold);678 679static ssize_t bb_ctrl_show(struct device *dev,680			    struct device_attribute *attr,681			    char *buf)682{683	unsigned long val;684	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);685	struct etmv4_config *config = &drvdata->config;686 687	val = config->bb_ctrl;688	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);689}690 691static ssize_t bb_ctrl_store(struct device *dev,692			     struct device_attribute *attr,693			     const char *buf, size_t size)694{695	unsigned long val;696	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);697	struct etmv4_config *config = &drvdata->config;698 699	if (kstrtoul(buf, 16, &val))700		return -EINVAL;701	if (drvdata->trcbb == false)702		return -EINVAL;703	if (!drvdata->nr_addr_cmp)704		return -EINVAL;705 706	/*707	 * Bit[8] controls include(1) / exclude(0), bits[0-7] select708	 * individual range comparators. If include then at least 1709	 * range must be selected.710	 */711	if ((val & TRCBBCTLR_MODE) && (FIELD_GET(TRCBBCTLR_RANGE_MASK, val) == 0))712		return -EINVAL;713 714	config->bb_ctrl = val & (TRCBBCTLR_MODE | TRCBBCTLR_RANGE_MASK);715	return size;716}717static DEVICE_ATTR_RW(bb_ctrl);718 719static ssize_t event_vinst_show(struct device *dev,720				struct device_attribute *attr,721				char *buf)722{723	unsigned long val;724	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);725	struct etmv4_config *config = &drvdata->config;726 727	val = FIELD_GET(TRCVICTLR_EVENT_MASK, config->vinst_ctrl);728	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);729}730 731static ssize_t event_vinst_store(struct device *dev,732				 struct device_attribute *attr,733				 const char *buf, size_t size)734{735	unsigned long val;736	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);737	struct etmv4_config *config = &drvdata->config;738 739	if (kstrtoul(buf, 16, &val))740		return -EINVAL;741 742	spin_lock(&drvdata->spinlock);743	val &= TRCVICTLR_EVENT_MASK >> __bf_shf(TRCVICTLR_EVENT_MASK);744	config->vinst_ctrl &= ~TRCVICTLR_EVENT_MASK;745	config->vinst_ctrl |= FIELD_PREP(TRCVICTLR_EVENT_MASK, val);746	spin_unlock(&drvdata->spinlock);747	return size;748}749static DEVICE_ATTR_RW(event_vinst);750 751static ssize_t s_exlevel_vinst_show(struct device *dev,752				    struct device_attribute *attr,753				    char *buf)754{755	unsigned long val;756	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);757	struct etmv4_config *config = &drvdata->config;758 759	val = FIELD_GET(TRCVICTLR_EXLEVEL_S_MASK, config->vinst_ctrl);760	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);761}762 763static ssize_t s_exlevel_vinst_store(struct device *dev,764				     struct device_attribute *attr,765				     const char *buf, size_t size)766{767	unsigned long val;768	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);769	struct etmv4_config *config = &drvdata->config;770 771	if (kstrtoul(buf, 16, &val))772		return -EINVAL;773 774	spin_lock(&drvdata->spinlock);775	/* clear all EXLEVEL_S bits  */776	config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_S_MASK;777	/* enable instruction tracing for corresponding exception level */778	val &= drvdata->s_ex_level;779	config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_S_MASK);780	spin_unlock(&drvdata->spinlock);781	return size;782}783static DEVICE_ATTR_RW(s_exlevel_vinst);784 785static ssize_t ns_exlevel_vinst_show(struct device *dev,786				     struct device_attribute *attr,787				     char *buf)788{789	unsigned long val;790	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);791	struct etmv4_config *config = &drvdata->config;792 793	/* EXLEVEL_NS, bits[23:20] */794	val = FIELD_GET(TRCVICTLR_EXLEVEL_NS_MASK, config->vinst_ctrl);795	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);796}797 798static ssize_t ns_exlevel_vinst_store(struct device *dev,799				      struct device_attribute *attr,800				      const char *buf, size_t size)801{802	unsigned long val;803	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);804	struct etmv4_config *config = &drvdata->config;805 806	if (kstrtoul(buf, 16, &val))807		return -EINVAL;808 809	spin_lock(&drvdata->spinlock);810	/* clear EXLEVEL_NS bits  */811	config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_NS_MASK;812	/* enable instruction tracing for corresponding exception level */813	val &= drvdata->ns_ex_level;814	config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_NS_MASK);815	spin_unlock(&drvdata->spinlock);816	return size;817}818static DEVICE_ATTR_RW(ns_exlevel_vinst);819 820static ssize_t addr_idx_show(struct device *dev,821			     struct device_attribute *attr,822			     char *buf)823{824	unsigned long val;825	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);826	struct etmv4_config *config = &drvdata->config;827 828	val = config->addr_idx;829	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);830}831 832static ssize_t addr_idx_store(struct device *dev,833			      struct device_attribute *attr,834			      const char *buf, size_t size)835{836	unsigned long val;837	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);838	struct etmv4_config *config = &drvdata->config;839 840	if (kstrtoul(buf, 16, &val))841		return -EINVAL;842	if (val >= drvdata->nr_addr_cmp * 2)843		return -EINVAL;844 845	/*846	 * Use spinlock to ensure index doesn't change while it gets847	 * dereferenced multiple times within a spinlock block elsewhere.848	 */849	spin_lock(&drvdata->spinlock);850	config->addr_idx = val;851	spin_unlock(&drvdata->spinlock);852	return size;853}854static DEVICE_ATTR_RW(addr_idx);855 856static ssize_t addr_instdatatype_show(struct device *dev,857				      struct device_attribute *attr,858				      char *buf)859{860	ssize_t len;861	u8 val, idx;862	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);863	struct etmv4_config *config = &drvdata->config;864 865	spin_lock(&drvdata->spinlock);866	idx = config->addr_idx;867	val = FIELD_GET(TRCACATRn_TYPE_MASK, config->addr_acc[idx]);868	len = scnprintf(buf, PAGE_SIZE, "%s\n",869			val == TRCACATRn_TYPE_ADDR ? "instr" :870			(val == TRCACATRn_TYPE_DATA_LOAD_ADDR ? "data_load" :871			(val == TRCACATRn_TYPE_DATA_STORE_ADDR ? "data_store" :872			"data_load_store")));873	spin_unlock(&drvdata->spinlock);874	return len;875}876 877static ssize_t addr_instdatatype_store(struct device *dev,878				       struct device_attribute *attr,879				       const char *buf, size_t size)880{881	u8 idx;882	char str[20] = "";883	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);884	struct etmv4_config *config = &drvdata->config;885 886	if (strlen(buf) >= 20)887		return -EINVAL;888	if (sscanf(buf, "%s", str) != 1)889		return -EINVAL;890 891	spin_lock(&drvdata->spinlock);892	idx = config->addr_idx;893	if (!strcmp(str, "instr"))894		/* TYPE, bits[1:0] */895		config->addr_acc[idx] &= ~TRCACATRn_TYPE_MASK;896 897	spin_unlock(&drvdata->spinlock);898	return size;899}900static DEVICE_ATTR_RW(addr_instdatatype);901 902static ssize_t addr_single_show(struct device *dev,903				struct device_attribute *attr,904				char *buf)905{906	u8 idx;907	unsigned long val;908	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);909	struct etmv4_config *config = &drvdata->config;910 911	idx = config->addr_idx;912	spin_lock(&drvdata->spinlock);913	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||914	      config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {915		spin_unlock(&drvdata->spinlock);916		return -EPERM;917	}918	val = (unsigned long)config->addr_val[idx];919	spin_unlock(&drvdata->spinlock);920	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);921}922 923static ssize_t addr_single_store(struct device *dev,924				 struct device_attribute *attr,925				 const char *buf, size_t size)926{927	u8 idx;928	unsigned long val;929	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);930	struct etmv4_config *config = &drvdata->config;931 932	if (kstrtoul(buf, 16, &val))933		return -EINVAL;934 935	spin_lock(&drvdata->spinlock);936	idx = config->addr_idx;937	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||938	      config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {939		spin_unlock(&drvdata->spinlock);940		return -EPERM;941	}942 943	config->addr_val[idx] = (u64)val;944	config->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;945	spin_unlock(&drvdata->spinlock);946	return size;947}948static DEVICE_ATTR_RW(addr_single);949 950static ssize_t addr_range_show(struct device *dev,951			       struct device_attribute *attr,952			       char *buf)953{954	u8 idx;955	unsigned long val1, val2;956	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);957	struct etmv4_config *config = &drvdata->config;958 959	spin_lock(&drvdata->spinlock);960	idx = config->addr_idx;961	if (idx % 2 != 0) {962		spin_unlock(&drvdata->spinlock);963		return -EPERM;964	}965	if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&966	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||967	      (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&968	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {969		spin_unlock(&drvdata->spinlock);970		return -EPERM;971	}972 973	val1 = (unsigned long)config->addr_val[idx];974	val2 = (unsigned long)config->addr_val[idx + 1];975	spin_unlock(&drvdata->spinlock);976	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);977}978 979static ssize_t addr_range_store(struct device *dev,980				struct device_attribute *attr,981				const char *buf, size_t size)982{983	u8 idx;984	unsigned long val1, val2;985	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);986	struct etmv4_config *config = &drvdata->config;987	int elements, exclude;988 989	elements = sscanf(buf, "%lx %lx %x", &val1, &val2, &exclude);990 991	/*  exclude is optional, but need at least two parameter */992	if (elements < 2)993		return -EINVAL;994	/* lower address comparator cannot have a higher address value */995	if (val1 > val2)996		return -EINVAL;997 998	spin_lock(&drvdata->spinlock);999	idx = config->addr_idx;1000	if (idx % 2 != 0) {1001		spin_unlock(&drvdata->spinlock);1002		return -EPERM;1003	}1004 1005	if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&1006	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||1007	      (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&1008	       config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {1009		spin_unlock(&drvdata->spinlock);1010		return -EPERM;1011	}1012 1013	config->addr_val[idx] = (u64)val1;1014	config->addr_type[idx] = ETM_ADDR_TYPE_RANGE;1015	config->addr_val[idx + 1] = (u64)val2;1016	config->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;1017	/*1018	 * Program include or exclude control bits for vinst or vdata1019	 * whenever we change addr comparators to ETM_ADDR_TYPE_RANGE1020	 * use supplied value, or default to bit set in 'mode'1021	 */1022	if (elements != 3)1023		exclude = config->mode & ETM_MODE_EXCLUDE;1024	etm4_set_mode_exclude(drvdata, exclude ? true : false);1025 1026	spin_unlock(&drvdata->spinlock);1027	return size;1028}1029static DEVICE_ATTR_RW(addr_range);1030 1031static ssize_t addr_start_show(struct device *dev,1032			       struct device_attribute *attr,1033			       char *buf)1034{1035	u8 idx;1036	unsigned long val;1037	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1038	struct etmv4_config *config = &drvdata->config;1039 1040	spin_lock(&drvdata->spinlock);1041	idx = config->addr_idx;1042 1043	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||1044	      config->addr_type[idx] == ETM_ADDR_TYPE_START)) {1045		spin_unlock(&drvdata->spinlock);1046		return -EPERM;1047	}1048 1049	val = (unsigned long)config->addr_val[idx];1050	spin_unlock(&drvdata->spinlock);1051	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1052}1053 1054static ssize_t addr_start_store(struct device *dev,1055				struct device_attribute *attr,1056				const char *buf, size_t size)1057{1058	u8 idx;1059	unsigned long val;1060	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1061	struct etmv4_config *config = &drvdata->config;1062 1063	if (kstrtoul(buf, 16, &val))1064		return -EINVAL;1065 1066	spin_lock(&drvdata->spinlock);1067	idx = config->addr_idx;1068	if (!drvdata->nr_addr_cmp) {1069		spin_unlock(&drvdata->spinlock);1070		return -EINVAL;1071	}1072	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||1073	      config->addr_type[idx] == ETM_ADDR_TYPE_START)) {1074		spin_unlock(&drvdata->spinlock);1075		return -EPERM;1076	}1077 1078	config->addr_val[idx] = (u64)val;1079	config->addr_type[idx] = ETM_ADDR_TYPE_START;1080	config->vissctlr |= BIT(idx);1081	spin_unlock(&drvdata->spinlock);1082	return size;1083}1084static DEVICE_ATTR_RW(addr_start);1085 1086static ssize_t addr_stop_show(struct device *dev,1087			      struct device_attribute *attr,1088			      char *buf)1089{1090	u8 idx;1091	unsigned long val;1092	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1093	struct etmv4_config *config = &drvdata->config;1094 1095	spin_lock(&drvdata->spinlock);1096	idx = config->addr_idx;1097 1098	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||1099	      config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {1100		spin_unlock(&drvdata->spinlock);1101		return -EPERM;1102	}1103 1104	val = (unsigned long)config->addr_val[idx];1105	spin_unlock(&drvdata->spinlock);1106	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1107}1108 1109static ssize_t addr_stop_store(struct device *dev,1110			       struct device_attribute *attr,1111			       const char *buf, size_t size)1112{1113	u8 idx;1114	unsigned long val;1115	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1116	struct etmv4_config *config = &drvdata->config;1117 1118	if (kstrtoul(buf, 16, &val))1119		return -EINVAL;1120 1121	spin_lock(&drvdata->spinlock);1122	idx = config->addr_idx;1123	if (!drvdata->nr_addr_cmp) {1124		spin_unlock(&drvdata->spinlock);1125		return -EINVAL;1126	}1127	if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||1128	       config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {1129		spin_unlock(&drvdata->spinlock);1130		return -EPERM;1131	}1132 1133	config->addr_val[idx] = (u64)val;1134	config->addr_type[idx] = ETM_ADDR_TYPE_STOP;1135	config->vissctlr |= BIT(idx + 16);1136	spin_unlock(&drvdata->spinlock);1137	return size;1138}1139static DEVICE_ATTR_RW(addr_stop);1140 1141static ssize_t addr_ctxtype_show(struct device *dev,1142				 struct device_attribute *attr,1143				 char *buf)1144{1145	ssize_t len;1146	u8 idx, val;1147	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1148	struct etmv4_config *config = &drvdata->config;1149 1150	spin_lock(&drvdata->spinlock);1151	idx = config->addr_idx;1152	/* CONTEXTTYPE, bits[3:2] */1153	val = FIELD_GET(TRCACATRn_CONTEXTTYPE_MASK, config->addr_acc[idx]);1154	len = scnprintf(buf, PAGE_SIZE, "%s\n", val == ETM_CTX_NONE ? "none" :1155			(val == ETM_CTX_CTXID ? "ctxid" :1156			(val == ETM_CTX_VMID ? "vmid" : "all")));1157	spin_unlock(&drvdata->spinlock);1158	return len;1159}1160 1161static ssize_t addr_ctxtype_store(struct device *dev,1162				  struct device_attribute *attr,1163				  const char *buf, size_t size)1164{1165	u8 idx;1166	char str[10] = "";1167	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1168	struct etmv4_config *config = &drvdata->config;1169 1170	if (strlen(buf) >= 10)1171		return -EINVAL;1172	if (sscanf(buf, "%s", str) != 1)1173		return -EINVAL;1174 1175	spin_lock(&drvdata->spinlock);1176	idx = config->addr_idx;1177	if (!strcmp(str, "none"))1178		/* start by clearing context type bits */1179		config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_MASK;1180	else if (!strcmp(str, "ctxid")) {1181		/* 0b01 The trace unit performs a Context ID */1182		if (drvdata->numcidc) {1183			config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_CTXID;1184			config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_VMID;1185		}1186	} else if (!strcmp(str, "vmid")) {1187		/* 0b10 The trace unit performs a VMID */1188		if (drvdata->numvmidc) {1189			config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_CTXID;1190			config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;1191		}1192	} else if (!strcmp(str, "all")) {1193		/*1194		 * 0b11 The trace unit performs a Context ID1195		 * comparison and a VMID1196		 */1197		if (drvdata->numcidc)1198			config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_CTXID;1199		if (drvdata->numvmidc)1200			config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;1201	}1202	spin_unlock(&drvdata->spinlock);1203	return size;1204}1205static DEVICE_ATTR_RW(addr_ctxtype);1206 1207static ssize_t addr_context_show(struct device *dev,1208				 struct device_attribute *attr,1209				 char *buf)1210{1211	u8 idx;1212	unsigned long val;1213	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1214	struct etmv4_config *config = &drvdata->config;1215 1216	spin_lock(&drvdata->spinlock);1217	idx = config->addr_idx;1218	/* context ID comparator bits[6:4] */1219	val = FIELD_GET(TRCACATRn_CONTEXT_MASK, config->addr_acc[idx]);1220	spin_unlock(&drvdata->spinlock);1221	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1222}1223 1224static ssize_t addr_context_store(struct device *dev,1225				  struct device_attribute *attr,1226				  const char *buf, size_t size)1227{1228	u8 idx;1229	unsigned long val;1230	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1231	struct etmv4_config *config = &drvdata->config;1232 1233	if (kstrtoul(buf, 16, &val))1234		return -EINVAL;1235	if ((drvdata->numcidc <= 1) && (drvdata->numvmidc <= 1))1236		return -EINVAL;1237	if (val >=  (drvdata->numcidc >= drvdata->numvmidc ?1238		     drvdata->numcidc : drvdata->numvmidc))1239		return -EINVAL;1240 1241	spin_lock(&drvdata->spinlock);1242	idx = config->addr_idx;1243	/* clear context ID comparator bits[6:4] */1244	config->addr_acc[idx] &= ~TRCACATRn_CONTEXT_MASK;1245	config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_CONTEXT_MASK);1246	spin_unlock(&drvdata->spinlock);1247	return size;1248}1249static DEVICE_ATTR_RW(addr_context);1250 1251static ssize_t addr_exlevel_s_ns_show(struct device *dev,1252				      struct device_attribute *attr,1253				      char *buf)1254{1255	u8 idx;1256	unsigned long val;1257	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1258	struct etmv4_config *config = &drvdata->config;1259 1260	spin_lock(&drvdata->spinlock);1261	idx = config->addr_idx;1262	val = FIELD_GET(TRCACATRn_EXLEVEL_MASK, config->addr_acc[idx]);1263	spin_unlock(&drvdata->spinlock);1264	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1265}1266 1267static ssize_t addr_exlevel_s_ns_store(struct device *dev,1268				       struct device_attribute *attr,1269				       const char *buf, size_t size)1270{1271	u8 idx;1272	unsigned long val;1273	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1274	struct etmv4_config *config = &drvdata->config;1275 1276	if (kstrtoul(buf, 0, &val))1277		return -EINVAL;1278 1279	if (val & ~(TRCACATRn_EXLEVEL_MASK >> __bf_shf(TRCACATRn_EXLEVEL_MASK)))1280		return -EINVAL;1281 1282	spin_lock(&drvdata->spinlock);1283	idx = config->addr_idx;1284	/* clear Exlevel_ns & Exlevel_s bits[14:12, 11:8], bit[15] is res0 */1285	config->addr_acc[idx] &= ~TRCACATRn_EXLEVEL_MASK;1286	config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_EXLEVEL_MASK);1287	spin_unlock(&drvdata->spinlock);1288	return size;1289}1290static DEVICE_ATTR_RW(addr_exlevel_s_ns);1291 1292static const char * const addr_type_names[] = {1293	"unused",1294	"single",1295	"range",1296	"start",1297	"stop"1298};1299 1300static ssize_t addr_cmp_view_show(struct device *dev,1301				  struct device_attribute *attr, char *buf)1302{1303	u8 idx, addr_type;1304	unsigned long addr_v, addr_v2, addr_ctrl;1305	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1306	struct etmv4_config *config = &drvdata->config;1307	int size = 0;1308	bool exclude = false;1309 1310	spin_lock(&drvdata->spinlock);1311	idx = config->addr_idx;1312	addr_v = config->addr_val[idx];1313	addr_ctrl = config->addr_acc[idx];1314	addr_type = config->addr_type[idx];1315	if (addr_type == ETM_ADDR_TYPE_RANGE) {1316		if (idx & 0x1) {1317			idx -= 1;1318			addr_v2 = addr_v;1319			addr_v = config->addr_val[idx];1320		} else {1321			addr_v2 = config->addr_val[idx + 1];1322		}1323		exclude = config->viiectlr & BIT(idx / 2 + 16);1324	}1325	spin_unlock(&drvdata->spinlock);1326	if (addr_type) {1327		size = scnprintf(buf, PAGE_SIZE, "addr_cmp[%i] %s %#lx", idx,1328				 addr_type_names[addr_type], addr_v);1329		if (addr_type == ETM_ADDR_TYPE_RANGE) {1330			size += scnprintf(buf + size, PAGE_SIZE - size,1331					  " %#lx %s", addr_v2,1332					  exclude ? "exclude" : "include");1333		}1334		size += scnprintf(buf + size, PAGE_SIZE - size,1335				  " ctrl(%#lx)\n", addr_ctrl);1336	} else {1337		size = scnprintf(buf, PAGE_SIZE, "addr_cmp[%i] unused\n", idx);1338	}1339	return size;1340}1341static DEVICE_ATTR_RO(addr_cmp_view);1342 1343static ssize_t vinst_pe_cmp_start_stop_show(struct device *dev,1344					    struct device_attribute *attr,1345					    char *buf)1346{1347	unsigned long val;1348	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1349	struct etmv4_config *config = &drvdata->config;1350 1351	if (!drvdata->nr_pe_cmp)1352		return -EINVAL;1353	val = config->vipcssctlr;1354	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1355}1356static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,1357					     struct device_attribute *attr,1358					     const char *buf, size_t size)1359{1360	unsigned long val;1361	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1362	struct etmv4_config *config = &drvdata->config;1363 1364	if (kstrtoul(buf, 16, &val))1365		return -EINVAL;1366	if (!drvdata->nr_pe_cmp)1367		return -EINVAL;1368 1369	spin_lock(&drvdata->spinlock);1370	config->vipcssctlr = val;1371	spin_unlock(&drvdata->spinlock);1372	return size;1373}1374static DEVICE_ATTR_RW(vinst_pe_cmp_start_stop);1375 1376static ssize_t seq_idx_show(struct device *dev,1377			    struct device_attribute *attr,1378			    char *buf)1379{1380	unsigned long val;1381	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1382	struct etmv4_config *config = &drvdata->config;1383 1384	val = config->seq_idx;1385	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1386}1387 1388static ssize_t seq_idx_store(struct device *dev,1389			     struct device_attribute *attr,1390			     const char *buf, size_t size)1391{1392	unsigned long val;1393	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1394	struct etmv4_config *config = &drvdata->config;1395 1396	if (kstrtoul(buf, 16, &val))1397		return -EINVAL;1398	if (val >= drvdata->nrseqstate - 1)1399		return -EINVAL;1400 1401	/*1402	 * Use spinlock to ensure index doesn't change while it gets1403	 * dereferenced multiple times within a spinlock block elsewhere.1404	 */1405	spin_lock(&drvdata->spinlock);1406	config->seq_idx = val;1407	spin_unlock(&drvdata->spinlock);1408	return size;1409}1410static DEVICE_ATTR_RW(seq_idx);1411 1412static ssize_t seq_state_show(struct device *dev,1413			      struct device_attribute *attr,1414			      char *buf)1415{1416	unsigned long val;1417	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1418	struct etmv4_config *config = &drvdata->config;1419 1420	val = config->seq_state;1421	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1422}1423 1424static ssize_t seq_state_store(struct device *dev,1425			       struct device_attribute *attr,1426			       const char *buf, size_t size)1427{1428	unsigned long val;1429	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1430	struct etmv4_config *config = &drvdata->config;1431 1432	if (kstrtoul(buf, 16, &val))1433		return -EINVAL;1434	if (val >= drvdata->nrseqstate)1435		return -EINVAL;1436 1437	config->seq_state = val;1438	return size;1439}1440static DEVICE_ATTR_RW(seq_state);1441 1442static ssize_t seq_event_show(struct device *dev,1443			      struct device_attribute *attr,1444			      char *buf)1445{1446	u8 idx;1447	unsigned long val;1448	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1449	struct etmv4_config *config = &drvdata->config;1450 1451	spin_lock(&drvdata->spinlock);1452	idx = config->seq_idx;1453	val = config->seq_ctrl[idx];1454	spin_unlock(&drvdata->spinlock);1455	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1456}1457 1458static ssize_t seq_event_store(struct device *dev,1459			       struct device_attribute *attr,1460			       const char *buf, size_t size)1461{1462	u8 idx;1463	unsigned long val;1464	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1465	struct etmv4_config *config = &drvdata->config;1466 1467	if (kstrtoul(buf, 16, &val))1468		return -EINVAL;1469 1470	spin_lock(&drvdata->spinlock);1471	idx = config->seq_idx;1472	/* Seq control has two masks B[15:8] F[7:0] */1473	config->seq_ctrl[idx] = val & 0xFFFF;1474	spin_unlock(&drvdata->spinlock);1475	return size;1476}1477static DEVICE_ATTR_RW(seq_event);1478 1479static ssize_t seq_reset_event_show(struct device *dev,1480				    struct device_attribute *attr,1481				    char *buf)1482{1483	unsigned long val;1484	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1485	struct etmv4_config *config = &drvdata->config;1486 1487	val = config->seq_rst;1488	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1489}1490 1491static ssize_t seq_reset_event_store(struct device *dev,1492				     struct device_attribute *attr,1493				     const char *buf, size_t size)1494{1495	unsigned long val;1496	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1497	struct etmv4_config *config = &drvdata->config;1498 1499	if (kstrtoul(buf, 16, &val))1500		return -EINVAL;1501	if (!(drvdata->nrseqstate))1502		return -EINVAL;1503 1504	config->seq_rst = val & ETMv4_EVENT_MASK;1505	return size;1506}1507static DEVICE_ATTR_RW(seq_reset_event);1508 1509static ssize_t cntr_idx_show(struct device *dev,1510			     struct device_attribute *attr,1511			     char *buf)1512{1513	unsigned long val;1514	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1515	struct etmv4_config *config = &drvdata->config;1516 1517	val = config->cntr_idx;1518	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1519}1520 1521static ssize_t cntr_idx_store(struct device *dev,1522			      struct device_attribute *attr,1523			      const char *buf, size_t size)1524{1525	unsigned long val;1526	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1527	struct etmv4_config *config = &drvdata->config;1528 1529	if (kstrtoul(buf, 16, &val))1530		return -EINVAL;1531	if (val >= drvdata->nr_cntr)1532		return -EINVAL;1533 1534	/*1535	 * Use spinlock to ensure index doesn't change while it gets1536	 * dereferenced multiple times within a spinlock block elsewhere.1537	 */1538	spin_lock(&drvdata->spinlock);1539	config->cntr_idx = val;1540	spin_unlock(&drvdata->spinlock);1541	return size;1542}1543static DEVICE_ATTR_RW(cntr_idx);1544 1545static ssize_t cntrldvr_show(struct device *dev,1546			     struct device_attribute *attr,1547			     char *buf)1548{1549	u8 idx;1550	unsigned long val;1551	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1552	struct etmv4_config *config = &drvdata->config;1553 1554	spin_lock(&drvdata->spinlock);1555	idx = config->cntr_idx;1556	val = config->cntrldvr[idx];1557	spin_unlock(&drvdata->spinlock);1558	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1559}1560 1561static ssize_t cntrldvr_store(struct device *dev,1562			      struct device_attribute *attr,1563			      const char *buf, size_t size)1564{1565	u8 idx;1566	unsigned long val;1567	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1568	struct etmv4_config *config = &drvdata->config;1569 1570	if (kstrtoul(buf, 16, &val))1571		return -EINVAL;1572	if (val > ETM_CNTR_MAX_VAL)1573		return -EINVAL;1574 1575	spin_lock(&drvdata->spinlock);1576	idx = config->cntr_idx;1577	config->cntrldvr[idx] = val;1578	spin_unlock(&drvdata->spinlock);1579	return size;1580}1581static DEVICE_ATTR_RW(cntrldvr);1582 1583static ssize_t cntr_val_show(struct device *dev,1584			     struct device_attribute *attr,1585			     char *buf)1586{1587	u8 idx;1588	unsigned long val;1589	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1590	struct etmv4_config *config = &drvdata->config;1591 1592	spin_lock(&drvdata->spinlock);1593	idx = config->cntr_idx;1594	val = config->cntr_val[idx];1595	spin_unlock(&drvdata->spinlock);1596	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1597}1598 1599static ssize_t cntr_val_store(struct device *dev,1600			      struct device_attribute *attr,1601			      const char *buf, size_t size)1602{1603	u8 idx;1604	unsigned long val;1605	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1606	struct etmv4_config *config = &drvdata->config;1607 1608	if (kstrtoul(buf, 16, &val))1609		return -EINVAL;1610	if (val > ETM_CNTR_MAX_VAL)1611		return -EINVAL;1612 1613	spin_lock(&drvdata->spinlock);1614	idx = config->cntr_idx;1615	config->cntr_val[idx] = val;1616	spin_unlock(&drvdata->spinlock);1617	return size;1618}1619static DEVICE_ATTR_RW(cntr_val);1620 1621static ssize_t cntr_ctrl_show(struct device *dev,1622			      struct device_attribute *attr,1623			      char *buf)1624{1625	u8 idx;1626	unsigned long val;1627	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1628	struct etmv4_config *config = &drvdata->config;1629 1630	spin_lock(&drvdata->spinlock);1631	idx = config->cntr_idx;1632	val = config->cntr_ctrl[idx];1633	spin_unlock(&drvdata->spinlock);1634	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1635}1636 1637static ssize_t cntr_ctrl_store(struct device *dev,1638			       struct device_attribute *attr,1639			       const char *buf, size_t size)1640{1641	u8 idx;1642	unsigned long val;1643	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1644	struct etmv4_config *config = &drvdata->config;1645 1646	if (kstrtoul(buf, 16, &val))1647		return -EINVAL;1648 1649	spin_lock(&drvdata->spinlock);1650	idx = config->cntr_idx;1651	config->cntr_ctrl[idx] = val;1652	spin_unlock(&drvdata->spinlock);1653	return size;1654}1655static DEVICE_ATTR_RW(cntr_ctrl);1656 1657static ssize_t res_idx_show(struct device *dev,1658			    struct device_attribute *attr,1659			    char *buf)1660{1661	unsigned long val;1662	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1663	struct etmv4_config *config = &drvdata->config;1664 1665	val = config->res_idx;1666	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1667}1668 1669static ssize_t res_idx_store(struct device *dev,1670			     struct device_attribute *attr,1671			     const char *buf, size_t size)1672{1673	unsigned long val;1674	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1675	struct etmv4_config *config = &drvdata->config;1676 1677	if (kstrtoul(buf, 16, &val))1678		return -EINVAL;1679	/*1680	 * Resource selector pair 0 is always implemented and reserved,1681	 * namely an idx with 0 and 1 is illegal.1682	 */1683	if ((val < 2) || (val >= 2 * drvdata->nr_resource))1684		return -EINVAL;1685 1686	/*1687	 * Use spinlock to ensure index doesn't change while it gets1688	 * dereferenced multiple times within a spinlock block elsewhere.1689	 */1690	spin_lock(&drvdata->spinlock);1691	config->res_idx = val;1692	spin_unlock(&drvdata->spinlock);1693	return size;1694}1695static DEVICE_ATTR_RW(res_idx);1696 1697static ssize_t res_ctrl_show(struct device *dev,1698			     struct device_attribute *attr,1699			     char *buf)1700{1701	u8 idx;1702	unsigned long val;1703	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1704	struct etmv4_config *config = &drvdata->config;1705 1706	spin_lock(&drvdata->spinlock);1707	idx = config->res_idx;1708	val = config->res_ctrl[idx];1709	spin_unlock(&drvdata->spinlock);1710	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1711}1712 1713static ssize_t res_ctrl_store(struct device *dev,1714			      struct device_attribute *attr,1715			      const char *buf, size_t size)1716{1717	u8 idx;1718	unsigned long val;1719	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1720	struct etmv4_config *config = &drvdata->config;1721 1722	if (kstrtoul(buf, 16, &val))1723		return -EINVAL;1724 1725	spin_lock(&drvdata->spinlock);1726	idx = config->res_idx;1727	/* For odd idx pair inversal bit is RES0 */1728	if (idx % 2 != 0)1729		/* PAIRINV, bit[21] */1730		val &= ~TRCRSCTLRn_PAIRINV;1731	config->res_ctrl[idx] = val & (TRCRSCTLRn_PAIRINV |1732				       TRCRSCTLRn_INV |1733				       TRCRSCTLRn_GROUP_MASK |1734				       TRCRSCTLRn_SELECT_MASK);1735	spin_unlock(&drvdata->spinlock);1736	return size;1737}1738static DEVICE_ATTR_RW(res_ctrl);1739 1740static ssize_t sshot_idx_show(struct device *dev,1741			      struct device_attribute *attr, char *buf)1742{1743	unsigned long val;1744	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1745	struct etmv4_config *config = &drvdata->config;1746 1747	val = config->ss_idx;1748	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1749}1750 1751static ssize_t sshot_idx_store(struct device *dev,1752			       struct device_attribute *attr,1753			       const char *buf, size_t size)1754{1755	unsigned long val;1756	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1757	struct etmv4_config *config = &drvdata->config;1758 1759	if (kstrtoul(buf, 16, &val))1760		return -EINVAL;1761	if (val >= drvdata->nr_ss_cmp)1762		return -EINVAL;1763 1764	spin_lock(&drvdata->spinlock);1765	config->ss_idx = val;1766	spin_unlock(&drvdata->spinlock);1767	return size;1768}1769static DEVICE_ATTR_RW(sshot_idx);1770 1771static ssize_t sshot_ctrl_show(struct device *dev,1772			       struct device_attribute *attr,1773			       char *buf)1774{1775	unsigned long val;1776	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1777	struct etmv4_config *config = &drvdata->config;1778 1779	spin_lock(&drvdata->spinlock);1780	val = config->ss_ctrl[config->ss_idx];1781	spin_unlock(&drvdata->spinlock);1782	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1783}1784 1785static ssize_t sshot_ctrl_store(struct device *dev,1786				struct device_attribute *attr,1787				const char *buf, size_t size)1788{1789	u8 idx;1790	unsigned long val;1791	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1792	struct etmv4_config *config = &drvdata->config;1793 1794	if (kstrtoul(buf, 16, &val))1795		return -EINVAL;1796 1797	spin_lock(&drvdata->spinlock);1798	idx = config->ss_idx;1799	config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);1800	/* must clear bit 31 in related status register on programming */1801	config->ss_status[idx] &= ~TRCSSCSRn_STATUS;1802	spin_unlock(&drvdata->spinlock);1803	return size;1804}1805static DEVICE_ATTR_RW(sshot_ctrl);1806 1807static ssize_t sshot_status_show(struct device *dev,1808				 struct device_attribute *attr, char *buf)1809{1810	unsigned long val;1811	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1812	struct etmv4_config *config = &drvdata->config;1813 1814	spin_lock(&drvdata->spinlock);1815	val = config->ss_status[config->ss_idx];1816	spin_unlock(&drvdata->spinlock);1817	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1818}1819static DEVICE_ATTR_RO(sshot_status);1820 1821static ssize_t sshot_pe_ctrl_show(struct device *dev,1822				  struct device_attribute *attr,1823				  char *buf)1824{1825	unsigned long val;1826	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1827	struct etmv4_config *config = &drvdata->config;1828 1829	spin_lock(&drvdata->spinlock);1830	val = config->ss_pe_cmp[config->ss_idx];1831	spin_unlock(&drvdata->spinlock);1832	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1833}1834 1835static ssize_t sshot_pe_ctrl_store(struct device *dev,1836				   struct device_attribute *attr,1837				   const char *buf, size_t size)1838{1839	u8 idx;1840	unsigned long val;1841	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1842	struct etmv4_config *config = &drvdata->config;1843 1844	if (kstrtoul(buf, 16, &val))1845		return -EINVAL;1846 1847	spin_lock(&drvdata->spinlock);1848	idx = config->ss_idx;1849	config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);1850	/* must clear bit 31 in related status register on programming */1851	config->ss_status[idx] &= ~TRCSSCSRn_STATUS;1852	spin_unlock(&drvdata->spinlock);1853	return size;1854}1855static DEVICE_ATTR_RW(sshot_pe_ctrl);1856 1857static ssize_t ctxid_idx_show(struct device *dev,1858			      struct device_attribute *attr,1859			      char *buf)1860{1861	unsigned long val;1862	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1863	struct etmv4_config *config = &drvdata->config;1864 1865	val = config->ctxid_idx;1866	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1867}1868 1869static ssize_t ctxid_idx_store(struct device *dev,1870			       struct device_attribute *attr,1871			       const char *buf, size_t size)1872{1873	unsigned long val;1874	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1875	struct etmv4_config *config = &drvdata->config;1876 1877	if (kstrtoul(buf, 16, &val))1878		return -EINVAL;1879	if (val >= drvdata->numcidc)1880		return -EINVAL;1881 1882	/*1883	 * Use spinlock to ensure index doesn't change while it gets1884	 * dereferenced multiple times within a spinlock block elsewhere.1885	 */1886	spin_lock(&drvdata->spinlock);1887	config->ctxid_idx = val;1888	spin_unlock(&drvdata->spinlock);1889	return size;1890}1891static DEVICE_ATTR_RW(ctxid_idx);1892 1893static ssize_t ctxid_pid_show(struct device *dev,1894			      struct device_attribute *attr,1895			      char *buf)1896{1897	u8 idx;1898	unsigned long val;1899	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1900	struct etmv4_config *config = &drvdata->config;1901 1902	/*1903	 * Don't use contextID tracing if coming from a PID namespace.  See1904	 * comment in ctxid_pid_store().1905	 */1906	if (task_active_pid_ns(current) != &init_pid_ns)1907		return -EINVAL;1908 1909	spin_lock(&drvdata->spinlock);1910	idx = config->ctxid_idx;1911	val = (unsigned long)config->ctxid_pid[idx];1912	spin_unlock(&drvdata->spinlock);1913	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);1914}1915 1916static ssize_t ctxid_pid_store(struct device *dev,1917			       struct device_attribute *attr,1918			       const char *buf, size_t size)1919{1920	u8 idx;1921	unsigned long pid;1922	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1923	struct etmv4_config *config = &drvdata->config;1924 1925	/*1926	 * When contextID tracing is enabled the tracers will insert the1927	 * value found in the contextID register in the trace stream.  But if1928	 * a process is in a namespace the PID of that process as seen from the1929	 * namespace won't be what the kernel sees, something that makes the1930	 * feature confusing and can potentially leak kernel only information.1931	 * As such refuse to use the feature if @current is not in the initial1932	 * PID namespace.1933	 */1934	if (task_active_pid_ns(current) != &init_pid_ns)1935		return -EINVAL;1936 1937	/*1938	 * only implemented when ctxid tracing is enabled, i.e. at least one1939	 * ctxid comparator is implemented and ctxid is greater than 0 bits1940	 * in length1941	 */1942	if (!drvdata->ctxid_size || !drvdata->numcidc)1943		return -EINVAL;1944	if (kstrtoul(buf, 16, &pid))1945		return -EINVAL;1946 1947	spin_lock(&drvdata->spinlock);1948	idx = config->ctxid_idx;1949	config->ctxid_pid[idx] = (u64)pid;1950	spin_unlock(&drvdata->spinlock);1951	return size;1952}1953static DEVICE_ATTR_RW(ctxid_pid);1954 1955static ssize_t ctxid_masks_show(struct device *dev,1956				struct device_attribute *attr,1957				char *buf)1958{1959	unsigned long val1, val2;1960	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1961	struct etmv4_config *config = &drvdata->config;1962 1963	/*1964	 * Don't use contextID tracing if coming from a PID namespace.  See1965	 * comment in ctxid_pid_store().1966	 */1967	if (task_active_pid_ns(current) != &init_pid_ns)1968		return -EINVAL;1969 1970	spin_lock(&drvdata->spinlock);1971	val1 = config->ctxid_mask0;1972	val2 = config->ctxid_mask1;1973	spin_unlock(&drvdata->spinlock);1974	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);1975}1976 1977static ssize_t ctxid_masks_store(struct device *dev,1978				struct device_attribute *attr,1979				const char *buf, size_t size)1980{1981	u8 i, j, maskbyte;1982	unsigned long val1, val2, mask;1983	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);1984	struct etmv4_config *config = &drvdata->config;1985	int nr_inputs;1986 1987	/*1988	 * Don't use contextID tracing if coming from a PID namespace.  See1989	 * comment in ctxid_pid_store().1990	 */1991	if (task_active_pid_ns(current) != &init_pid_ns)1992		return -EINVAL;1993 1994	/*1995	 * only implemented when ctxid tracing is enabled, i.e. at least one1996	 * ctxid comparator is implemented and ctxid is greater than 0 bits1997	 * in length1998	 */1999	if (!drvdata->ctxid_size || !drvdata->numcidc)2000		return -EINVAL;2001	/* one mask if <= 4 comparators, two for up to 8 */2002	nr_inputs = sscanf(buf, "%lx %lx", &val1, &val2);2003	if ((drvdata->numcidc > 4) && (nr_inputs != 2))2004		return -EINVAL;2005 2006	spin_lock(&drvdata->spinlock);2007	/*2008	 * each byte[0..3] controls mask value applied to ctxid2009	 * comparator[0..3]2010	 */2011	switch (drvdata->numcidc) {2012	case 0x1:2013		/* COMP0, bits[7:0] */2014		config->ctxid_mask0 = val1 & 0xFF;2015		break;2016	case 0x2:2017		/* COMP1, bits[15:8] */2018		config->ctxid_mask0 = val1 & 0xFFFF;2019		break;2020	case 0x3:2021		/* COMP2, bits[23:16] */2022		config->ctxid_mask0 = val1 & 0xFFFFFF;2023		break;2024	case 0x4:2025		 /* COMP3, bits[31:24] */2026		config->ctxid_mask0 = val1;2027		break;2028	case 0x5:2029		/* COMP4, bits[7:0] */2030		config->ctxid_mask0 = val1;2031		config->ctxid_mask1 = val2 & 0xFF;2032		break;2033	case 0x6:2034		/* COMP5, bits[15:8] */2035		config->ctxid_mask0 = val1;2036		config->ctxid_mask1 = val2 & 0xFFFF;2037		break;2038	case 0x7:2039		/* COMP6, bits[23:16] */2040		config->ctxid_mask0 = val1;2041		config->ctxid_mask1 = val2 & 0xFFFFFF;2042		break;2043	case 0x8:2044		/* COMP7, bits[31:24] */2045		config->ctxid_mask0 = val1;2046		config->ctxid_mask1 = val2;2047		break;2048	default:2049		break;2050	}2051	/*2052	 * If software sets a mask bit to 1, it must program relevant byte2053	 * of ctxid comparator value 0x0, otherwise behavior is unpredictable.2054	 * For example, if bit[3] of ctxid_mask0 is 1, we must clear bits[31:24]2055	 * of ctxid comparator0 value (corresponding to byte 0) register.2056	 */2057	mask = config->ctxid_mask0;2058	for (i = 0; i < drvdata->numcidc; i++) {2059		/* mask value of corresponding ctxid comparator */2060		maskbyte = mask & ETMv4_EVENT_MASK;2061		/*2062		 * each bit corresponds to a byte of respective ctxid comparator2063		 * value register2064		 */2065		for (j = 0; j < 8; j++) {2066			if (maskbyte & 1)2067				config->ctxid_pid[i] &= ~(0xFFUL << (j * 8));2068			maskbyte >>= 1;2069		}2070		/* Select the next ctxid comparator mask value */2071		if (i == 3)2072			/* ctxid comparators[4-7] */2073			mask = config->ctxid_mask1;2074		else2075			mask >>= 0x8;2076	}2077 2078	spin_unlock(&drvdata->spinlock);2079	return size;2080}2081static DEVICE_ATTR_RW(ctxid_masks);2082 2083static ssize_t vmid_idx_show(struct device *dev,2084			     struct device_attribute *attr,2085			     char *buf)2086{2087	unsigned long val;2088	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2089	struct etmv4_config *config = &drvdata->config;2090 2091	val = config->vmid_idx;2092	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);2093}2094 2095static ssize_t vmid_idx_store(struct device *dev,2096			      struct device_attribute *attr,2097			      const char *buf, size_t size)2098{2099	unsigned long val;2100	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2101	struct etmv4_config *config = &drvdata->config;2102 2103	if (kstrtoul(buf, 16, &val))2104		return -EINVAL;2105	if (val >= drvdata->numvmidc)2106		return -EINVAL;2107 2108	/*2109	 * Use spinlock to ensure index doesn't change while it gets2110	 * dereferenced multiple times within a spinlock block elsewhere.2111	 */2112	spin_lock(&drvdata->spinlock);2113	config->vmid_idx = val;2114	spin_unlock(&drvdata->spinlock);2115	return size;2116}2117static DEVICE_ATTR_RW(vmid_idx);2118 2119static ssize_t vmid_val_show(struct device *dev,2120			     struct device_attribute *attr,2121			     char *buf)2122{2123	unsigned long val;2124	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2125	struct etmv4_config *config = &drvdata->config;2126 2127	/*2128	 * Don't use virtual contextID tracing if coming from a PID namespace.2129	 * See comment in ctxid_pid_store().2130	 */2131	if (!task_is_in_init_pid_ns(current))2132		return -EINVAL;2133 2134	spin_lock(&drvdata->spinlock);2135	val = (unsigned long)config->vmid_val[config->vmid_idx];2136	spin_unlock(&drvdata->spinlock);2137	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);2138}2139 2140static ssize_t vmid_val_store(struct device *dev,2141			      struct device_attribute *attr,2142			      const char *buf, size_t size)2143{2144	unsigned long val;2145	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2146	struct etmv4_config *config = &drvdata->config;2147 2148	/*2149	 * Don't use virtual contextID tracing if coming from a PID namespace.2150	 * See comment in ctxid_pid_store().2151	 */2152	if (!task_is_in_init_pid_ns(current))2153		return -EINVAL;2154 2155	/*2156	 * only implemented when vmid tracing is enabled, i.e. at least one2157	 * vmid comparator is implemented and at least 8 bit vmid size2158	 */2159	if (!drvdata->vmid_size || !drvdata->numvmidc)2160		return -EINVAL;2161	if (kstrtoul(buf, 16, &val))2162		return -EINVAL;2163 2164	spin_lock(&drvdata->spinlock);2165	config->vmid_val[config->vmid_idx] = (u64)val;2166	spin_unlock(&drvdata->spinlock);2167	return size;2168}2169static DEVICE_ATTR_RW(vmid_val);2170 2171static ssize_t vmid_masks_show(struct device *dev,2172			       struct device_attribute *attr, char *buf)2173{2174	unsigned long val1, val2;2175	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2176	struct etmv4_config *config = &drvdata->config;2177 2178	/*2179	 * Don't use virtual contextID tracing if coming from a PID namespace.2180	 * See comment in ctxid_pid_store().2181	 */2182	if (!task_is_in_init_pid_ns(current))2183		return -EINVAL;2184 2185	spin_lock(&drvdata->spinlock);2186	val1 = config->vmid_mask0;2187	val2 = config->vmid_mask1;2188	spin_unlock(&drvdata->spinlock);2189	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);2190}2191 2192static ssize_t vmid_masks_store(struct device *dev,2193				struct device_attribute *attr,2194				const char *buf, size_t size)2195{2196	u8 i, j, maskbyte;2197	unsigned long val1, val2, mask;2198	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2199	struct etmv4_config *config = &drvdata->config;2200	int nr_inputs;2201 2202	/*2203	 * Don't use virtual contextID tracing if coming from a PID namespace.2204	 * See comment in ctxid_pid_store().2205	 */2206	if (!task_is_in_init_pid_ns(current))2207		return -EINVAL;2208 2209	/*2210	 * only implemented when vmid tracing is enabled, i.e. at least one2211	 * vmid comparator is implemented and at least 8 bit vmid size2212	 */2213	if (!drvdata->vmid_size || !drvdata->numvmidc)2214		return -EINVAL;2215	/* one mask if <= 4 comparators, two for up to 8 */2216	nr_inputs = sscanf(buf, "%lx %lx", &val1, &val2);2217	if ((drvdata->numvmidc > 4) && (nr_inputs != 2))2218		return -EINVAL;2219 2220	spin_lock(&drvdata->spinlock);2221 2222	/*2223	 * each byte[0..3] controls mask value applied to vmid2224	 * comparator[0..3]2225	 */2226	switch (drvdata->numvmidc) {2227	case 0x1:2228		/* COMP0, bits[7:0] */2229		config->vmid_mask0 = val1 & 0xFF;2230		break;2231	case 0x2:2232		/* COMP1, bits[15:8] */2233		config->vmid_mask0 = val1 & 0xFFFF;2234		break;2235	case 0x3:2236		/* COMP2, bits[23:16] */2237		config->vmid_mask0 = val1 & 0xFFFFFF;2238		break;2239	case 0x4:2240		/* COMP3, bits[31:24] */2241		config->vmid_mask0 = val1;2242		break;2243	case 0x5:2244		/* COMP4, bits[7:0] */2245		config->vmid_mask0 = val1;2246		config->vmid_mask1 = val2 & 0xFF;2247		break;2248	case 0x6:2249		/* COMP5, bits[15:8] */2250		config->vmid_mask0 = val1;2251		config->vmid_mask1 = val2 & 0xFFFF;2252		break;2253	case 0x7:2254		/* COMP6, bits[23:16] */2255		config->vmid_mask0 = val1;2256		config->vmid_mask1 = val2 & 0xFFFFFF;2257		break;2258	case 0x8:2259		/* COMP7, bits[31:24] */2260		config->vmid_mask0 = val1;2261		config->vmid_mask1 = val2;2262		break;2263	default:2264		break;2265	}2266 2267	/*2268	 * If software sets a mask bit to 1, it must program relevant byte2269	 * of vmid comparator value 0x0, otherwise behavior is unpredictable.2270	 * For example, if bit[3] of vmid_mask0 is 1, we must clear bits[31:24]2271	 * of vmid comparator0 value (corresponding to byte 0) register.2272	 */2273	mask = config->vmid_mask0;2274	for (i = 0; i < drvdata->numvmidc; i++) {2275		/* mask value of corresponding vmid comparator */2276		maskbyte = mask & ETMv4_EVENT_MASK;2277		/*2278		 * each bit corresponds to a byte of respective vmid comparator2279		 * value register2280		 */2281		for (j = 0; j < 8; j++) {2282			if (maskbyte & 1)2283				config->vmid_val[i] &= ~(0xFFUL << (j * 8));2284			maskbyte >>= 1;2285		}2286		/* Select the next vmid comparator mask value */2287		if (i == 3)2288			/* vmid comparators[4-7] */2289			mask = config->vmid_mask1;2290		else2291			mask >>= 0x8;2292	}2293	spin_unlock(&drvdata->spinlock);2294	return size;2295}2296static DEVICE_ATTR_RW(vmid_masks);2297 2298static ssize_t cpu_show(struct device *dev,2299			struct device_attribute *attr, char *buf)2300{2301	int val;2302	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2303 2304	val = drvdata->cpu;2305	return scnprintf(buf, PAGE_SIZE, "%d\n", val);2306 2307}2308static DEVICE_ATTR_RO(cpu);2309 2310static ssize_t ts_source_show(struct device *dev,2311			      struct device_attribute *attr,2312			      char *buf)2313{2314	int val;2315	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2316 2317	if (!drvdata->trfcr) {2318		val = -1;2319		goto out;2320	}2321 2322	switch (drvdata->trfcr & TRFCR_ELx_TS_MASK) {2323	case TRFCR_ELx_TS_VIRTUAL:2324	case TRFCR_ELx_TS_GUEST_PHYSICAL:2325	case TRFCR_ELx_TS_PHYSICAL:2326		val = FIELD_GET(TRFCR_ELx_TS_MASK, drvdata->trfcr);2327		break;2328	default:2329		val = -1;2330		break;2331	}2332 2333out:2334	return sysfs_emit(buf, "%d\n", val);2335}2336static DEVICE_ATTR_RO(ts_source);2337 2338static struct attribute *coresight_etmv4_attrs[] = {2339	&dev_attr_nr_pe_cmp.attr,2340	&dev_attr_nr_addr_cmp.attr,2341	&dev_attr_nr_cntr.attr,2342	&dev_attr_nr_ext_inp.attr,2343	&dev_attr_numcidc.attr,2344	&dev_attr_numvmidc.attr,2345	&dev_attr_nrseqstate.attr,2346	&dev_attr_nr_resource.attr,2347	&dev_attr_nr_ss_cmp.attr,2348	&dev_attr_reset.attr,2349	&dev_attr_mode.attr,2350	&dev_attr_pe.attr,2351	&dev_attr_event.attr,2352	&dev_attr_event_instren.attr,2353	&dev_attr_event_ts.attr,2354	&dev_attr_syncfreq.attr,2355	&dev_attr_cyc_threshold.attr,2356	&dev_attr_bb_ctrl.attr,2357	&dev_attr_event_vinst.attr,2358	&dev_attr_s_exlevel_vinst.attr,2359	&dev_attr_ns_exlevel_vinst.attr,2360	&dev_attr_addr_idx.attr,2361	&dev_attr_addr_instdatatype.attr,2362	&dev_attr_addr_single.attr,2363	&dev_attr_addr_range.attr,2364	&dev_attr_addr_start.attr,2365	&dev_attr_addr_stop.attr,2366	&dev_attr_addr_ctxtype.attr,2367	&dev_attr_addr_context.attr,2368	&dev_attr_addr_exlevel_s_ns.attr,2369	&dev_attr_addr_cmp_view.attr,2370	&dev_attr_vinst_pe_cmp_start_stop.attr,2371	&dev_attr_sshot_idx.attr,2372	&dev_attr_sshot_ctrl.attr,2373	&dev_attr_sshot_pe_ctrl.attr,2374	&dev_attr_sshot_status.attr,2375	&dev_attr_seq_idx.attr,2376	&dev_attr_seq_state.attr,2377	&dev_attr_seq_event.attr,2378	&dev_attr_seq_reset_event.attr,2379	&dev_attr_cntr_idx.attr,2380	&dev_attr_cntrldvr.attr,2381	&dev_attr_cntr_val.attr,2382	&dev_attr_cntr_ctrl.attr,2383	&dev_attr_res_idx.attr,2384	&dev_attr_res_ctrl.attr,2385	&dev_attr_ctxid_idx.attr,2386	&dev_attr_ctxid_pid.attr,2387	&dev_attr_ctxid_masks.attr,2388	&dev_attr_vmid_idx.attr,2389	&dev_attr_vmid_val.attr,2390	&dev_attr_vmid_masks.attr,2391	&dev_attr_cpu.attr,2392	&dev_attr_ts_source.attr,2393	NULL,2394};2395 2396/*2397 * Trace ID allocated dynamically on enable - but also allocate on read2398 * in case sysfs or perf read before enable to ensure consistent metadata2399 * information for trace decode2400 */2401static ssize_t trctraceid_show(struct device *dev,2402			       struct device_attribute *attr,2403			       char *buf)2404{2405	int trace_id;2406	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2407 2408	trace_id = etm4_read_alloc_trace_id(drvdata);2409	if (trace_id < 0)2410		return trace_id;2411 2412	return sysfs_emit(buf, "0x%x\n", trace_id);2413}2414 2415struct etmv4_reg {2416	struct coresight_device *csdev;2417	u32 offset;2418	u32 data;2419};2420 2421static void do_smp_cross_read(void *data)2422{2423	struct etmv4_reg *reg = data;2424 2425	reg->data = etm4x_relaxed_read32(&reg->csdev->access, reg->offset);2426}2427 2428static u32 etmv4_cross_read(const struct etmv4_drvdata *drvdata, u32 offset)2429{2430	struct etmv4_reg reg;2431 2432	reg.offset = offset;2433	reg.csdev = drvdata->csdev;2434 2435	/*2436	 * smp cross call ensures the CPU will be powered up before2437	 * accessing the ETMv4 trace core registers2438	 */2439	smp_call_function_single(drvdata->cpu, do_smp_cross_read, &reg, 1);2440	return reg.data;2441}2442 2443static inline u32 coresight_etm4x_attr_to_offset(struct device_attribute *attr)2444{2445	struct dev_ext_attribute *eattr;2446 2447	eattr = container_of(attr, struct dev_ext_attribute, attr);2448	return (u32)(unsigned long)eattr->var;2449}2450 2451static ssize_t coresight_etm4x_reg_show(struct device *dev,2452					struct device_attribute *d_attr,2453					char *buf)2454{2455	u32 val, offset;2456	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2457 2458	offset = coresight_etm4x_attr_to_offset(d_attr);2459 2460	pm_runtime_get_sync(dev->parent);2461	val = etmv4_cross_read(drvdata, offset);2462	pm_runtime_put_sync(dev->parent);2463 2464	return scnprintf(buf, PAGE_SIZE, "0x%x\n", val);2465}2466 2467static inline bool2468etm4x_register_implemented(struct etmv4_drvdata *drvdata, u32 offset)2469{2470	switch (offset) {2471	ETM_COMMON_SYSREG_LIST_CASES2472		/*2473		 * Common registers to ETE & ETM4x accessible via system2474		 * instructions are always implemented.2475		 */2476		return true;2477 2478	ETM4x_ONLY_SYSREG_LIST_CASES2479		/*2480		 * We only support etm4x and ete. So if the device is not2481		 * ETE, it must be ETMv4x.2482		 */2483		return !etm4x_is_ete(drvdata);2484 2485	ETM4x_MMAP_LIST_CASES2486		/*2487		 * Registers accessible only via memory-mapped registers2488		 * must not be accessed via system instructions.2489		 * We cannot access the drvdata->csdev here, as this2490		 * function is called during the device creation, via2491		 * coresight_register() and the csdev is not initialized2492		 * until that is done. So rely on the drvdata->base to2493		 * detect if we have a memory mapped access.2494		 * Also ETE doesn't implement memory mapped access, thus2495		 * it is sufficient to check that we are using mmio.2496		 */2497		return !!drvdata->base;2498 2499	ETE_ONLY_SYSREG_LIST_CASES2500		return etm4x_is_ete(drvdata);2501	}2502 2503	return false;2504}2505 2506/*2507 * Hide the ETM4x registers that may not be available on the2508 * hardware.2509 * There are certain management registers unavailable via system2510 * instructions. Make those sysfs attributes hidden on such2511 * systems.2512 */2513static umode_t2514coresight_etm4x_attr_reg_implemented(struct kobject *kobj,2515				     struct attribute *attr, int unused)2516{2517	struct device *dev = kobj_to_dev(kobj);2518	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);2519	struct device_attribute *d_attr;2520	u32 offset;2521 2522	d_attr = container_of(attr, struct device_attribute, attr);2523	offset = coresight_etm4x_attr_to_offset(d_attr);2524 2525	if (etm4x_register_implemented(drvdata, offset))2526		return attr->mode;2527	return 0;2528}2529 2530/*2531 * Macro to set an RO ext attribute with offset and show function.2532 * Offset is used in mgmt group to ensure only correct registers for2533 * the ETM / ETE variant are visible.2534 */2535#define coresight_etm4x_reg_showfn(name, offset, showfn) (	\2536	&((struct dev_ext_attribute[]) {			\2537	   {							\2538		__ATTR(name, 0444, showfn, NULL),		\2539		(void *)(unsigned long)offset			\2540	   }							\2541	})[0].attr.attr						\2542	)2543 2544/* macro using the default coresight_etm4x_reg_show function */2545#define coresight_etm4x_reg(name, offset)	\2546	coresight_etm4x_reg_showfn(name, offset, coresight_etm4x_reg_show)2547 2548static struct attribute *coresight_etmv4_mgmt_attrs[] = {2549	coresight_etm4x_reg(trcpdcr, TRCPDCR),2550	coresight_etm4x_reg(trcpdsr, TRCPDSR),2551	coresight_etm4x_reg(trclsr, TRCLSR),2552	coresight_etm4x_reg(trcauthstatus, TRCAUTHSTATUS),2553	coresight_etm4x_reg(trcdevid, TRCDEVID),2554	coresight_etm4x_reg(trcdevtype, TRCDEVTYPE),2555	coresight_etm4x_reg(trcpidr0, TRCPIDR0),2556	coresight_etm4x_reg(trcpidr1, TRCPIDR1),2557	coresight_etm4x_reg(trcpidr2, TRCPIDR2),2558	coresight_etm4x_reg(trcpidr3, TRCPIDR3),2559	coresight_etm4x_reg(trcoslsr, TRCOSLSR),2560	coresight_etm4x_reg(trcconfig, TRCCONFIGR),2561	coresight_etm4x_reg_showfn(trctraceid, TRCTRACEIDR, trctraceid_show),2562	coresight_etm4x_reg(trcdevarch, TRCDEVARCH),2563	NULL,2564};2565 2566static struct attribute *coresight_etmv4_trcidr_attrs[] = {2567	coresight_etm4x_reg(trcidr0, TRCIDR0),2568	coresight_etm4x_reg(trcidr1, TRCIDR1),2569	coresight_etm4x_reg(trcidr2, TRCIDR2),2570	coresight_etm4x_reg(trcidr3, TRCIDR3),2571	coresight_etm4x_reg(trcidr4, TRCIDR4),2572	coresight_etm4x_reg(trcidr5, TRCIDR5),2573	/* trcidr[6,7] are reserved */2574	coresight_etm4x_reg(trcidr8, TRCIDR8),2575	coresight_etm4x_reg(trcidr9, TRCIDR9),2576	coresight_etm4x_reg(trcidr10, TRCIDR10),2577	coresight_etm4x_reg(trcidr11, TRCIDR11),2578	coresight_etm4x_reg(trcidr12, TRCIDR12),2579	coresight_etm4x_reg(trcidr13, TRCIDR13),2580	NULL,2581};2582 2583static const struct attribute_group coresight_etmv4_group = {2584	.attrs = coresight_etmv4_attrs,2585};2586 2587static const struct attribute_group coresight_etmv4_mgmt_group = {2588	.is_visible = coresight_etm4x_attr_reg_implemented,2589	.attrs = coresight_etmv4_mgmt_attrs,2590	.name = "mgmt",2591};2592 2593static const struct attribute_group coresight_etmv4_trcidr_group = {2594	.attrs = coresight_etmv4_trcidr_attrs,2595	.name = "trcidr",2596};2597 2598const struct attribute_group *coresight_etmv4_groups[] = {2599	&coresight_etmv4_group,2600	&coresight_etmv4_mgmt_group,2601	&coresight_etmv4_trcidr_group,2602	NULL,2603};2604