forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
kernel/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
....@@ -205,8 +205,8 @@
205205 * started state. ARM recommends start-stop logic is set before
206206 * each trace run.
207207 */
208
- config->vinst_ctrl |= BIT(0);
209
- if (drvdata->nr_addr_cmp == true) {
208
+ config->vinst_ctrl = BIT(0);
209
+ if (drvdata->nr_addr_cmp > 0) {
210210 config->mode |= ETM_MODE_VIEWINST_STARTSTOP;
211211 /* SSSTATUS, bit[9] */
212212 config->vinst_ctrl |= BIT(9);
....@@ -217,6 +217,7 @@
217217
218218 /* No start-stop filtering for ViewInst */
219219 config->vissctlr = 0x0;
220
+ config->vipcssctlr = 0x0;
220221
221222 /* Disable seq events */
222223 for (i = 0; i < drvdata->nrseqstate-1; i++)
....@@ -235,9 +236,10 @@
235236 }
236237
237238 config->res_idx = 0x0;
238
- for (i = 0; i < drvdata->nr_resource; i++)
239
+ for (i = 2; i < 2 * drvdata->nr_resource; i++)
239240 config->res_ctrl[i] = 0x0;
240241
242
+ config->ss_idx = 0x0;
241243 for (i = 0; i < drvdata->nr_ss_cmp; i++) {
242244 config->ss_ctrl[i] = 0x0;
243245 config->ss_pe_cmp[i] = 0x0;
....@@ -296,11 +298,6 @@
296298
297299 spin_lock(&drvdata->spinlock);
298300 config->mode = val & ETMv4_MODE_ALL;
299
-
300
- if (config->mode & ETM_MODE_EXCLUDE)
301
- etm4_set_mode_exclude(drvdata, true);
302
- else
303
- etm4_set_mode_exclude(drvdata, false);
304301
305302 if (drvdata->instrp0 == true) {
306303 /* start by clearing instruction P0 field */
....@@ -367,8 +364,12 @@
367364 mode = ETM_MODE_QELEM(config->mode);
368365 /* start by clearing QE bits */
369366 config->cfg &= ~(BIT(13) | BIT(14));
370
- /* if supported, Q elements with instruction counts are enabled */
371
- if ((mode & BIT(0)) && (drvdata->q_support & BIT(0)))
367
+ /*
368
+ * if supported, Q elements with instruction counts are enabled.
369
+ * Always set the low bit for any requested mode. Valid combos are
370
+ * 0b00, 0b01 and 0b11.
371
+ */
372
+ if (mode && drvdata->q_support)
372373 config->cfg |= BIT(13);
373374 /*
374375 * if supported, Q elements with and without instruction
....@@ -392,7 +393,7 @@
392393 config->eventctrl1 &= ~BIT(12);
393394
394395 /* bit[8], Instruction stall bit */
395
- if (config->mode & ETM_MODE_ISTALL_EN)
396
+ if ((config->mode & ETM_MODE_ISTALL_EN) && (drvdata->stallctl == true))
396397 config->stall_ctrl |= BIT(8);
397398 else
398399 config->stall_ctrl &= ~BIT(8);
....@@ -746,7 +747,7 @@
746747 struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
747748 struct etmv4_config *config = &drvdata->config;
748749
749
- val = BMVAL(config->vinst_ctrl, 16, 19);
750
+ val = (config->vinst_ctrl & TRCVICTLR_EXLEVEL_S_MASK) >> TRCVICTLR_EXLEVEL_S_SHIFT;
750751 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
751752 }
752753
....@@ -762,11 +763,11 @@
762763 return -EINVAL;
763764
764765 spin_lock(&drvdata->spinlock);
765
- /* clear all EXLEVEL_S bits (bit[18] is never implemented) */
766
- config->vinst_ctrl &= ~(BIT(16) | BIT(17) | BIT(19));
766
+ /* clear all EXLEVEL_S bits */
767
+ config->vinst_ctrl &= ~(TRCVICTLR_EXLEVEL_S_MASK);
767768 /* enable instruction tracing for corresponding exception level */
768769 val &= drvdata->s_ex_level;
769
- config->vinst_ctrl |= (val << 16);
770
+ config->vinst_ctrl |= (val << TRCVICTLR_EXLEVEL_S_SHIFT);
770771 spin_unlock(&drvdata->spinlock);
771772 return size;
772773 }
....@@ -781,7 +782,7 @@
781782 struct etmv4_config *config = &drvdata->config;
782783
783784 /* EXLEVEL_NS, bits[23:20] */
784
- val = BMVAL(config->vinst_ctrl, 20, 23);
785
+ val = (config->vinst_ctrl & TRCVICTLR_EXLEVEL_NS_MASK) >> TRCVICTLR_EXLEVEL_NS_SHIFT;
785786 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
786787 }
787788
....@@ -797,11 +798,11 @@
797798 return -EINVAL;
798799
799800 spin_lock(&drvdata->spinlock);
800
- /* clear EXLEVEL_NS bits (bit[23] is never implemented */
801
- config->vinst_ctrl &= ~(BIT(20) | BIT(21) | BIT(22));
801
+ /* clear EXLEVEL_NS bits */
802
+ config->vinst_ctrl &= ~(TRCVICTLR_EXLEVEL_NS_MASK);
802803 /* enable instruction tracing for corresponding exception level */
803804 val &= drvdata->ns_ex_level;
804
- config->vinst_ctrl |= (val << 20);
805
+ config->vinst_ctrl |= (val << TRCVICTLR_EXLEVEL_NS_SHIFT);
805806 spin_unlock(&drvdata->spinlock);
806807 return size;
807808 }
....@@ -974,8 +975,12 @@
974975 unsigned long val1, val2;
975976 struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
976977 struct etmv4_config *config = &drvdata->config;
978
+ int elements, exclude;
977979
978
- if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
980
+ elements = sscanf(buf, "%lx %lx %x", &val1, &val2, &exclude);
981
+
982
+ /* exclude is optional, but need at least two parameter */
983
+ if (elements < 2)
979984 return -EINVAL;
980985 /* lower address comparator cannot have a higher address value */
981986 if (val1 > val2)
....@@ -1003,11 +1008,11 @@
10031008 /*
10041009 * Program include or exclude control bits for vinst or vdata
10051010 * whenever we change addr comparators to ETM_ADDR_TYPE_RANGE
1011
+ * use supplied value, or default to bit set in 'mode'
10061012 */
1007
- if (config->mode & ETM_MODE_EXCLUDE)
1008
- etm4_set_mode_exclude(drvdata, true);
1009
- else
1010
- etm4_set_mode_exclude(drvdata, false);
1013
+ if (elements != 3)
1014
+ exclude = config->mode & ETM_MODE_EXCLUDE;
1015
+ etm4_set_mode_exclude(drvdata, exclude ? true : false);
10111016
10121017 spin_unlock(&drvdata->spinlock);
10131018 return size;
....@@ -1064,8 +1069,6 @@
10641069 config->addr_val[idx] = (u64)val;
10651070 config->addr_type[idx] = ETM_ADDR_TYPE_START;
10661071 config->vissctlr |= BIT(idx);
1067
- /* SSSTATUS, bit[9] - turn on start/stop logic */
1068
- config->vinst_ctrl |= BIT(9);
10691072 spin_unlock(&drvdata->spinlock);
10701073 return size;
10711074 }
....@@ -1121,8 +1124,6 @@
11211124 config->addr_val[idx] = (u64)val;
11221125 config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
11231126 config->vissctlr |= BIT(idx + 16);
1124
- /* SSSTATUS, bit[9] - turn on start/stop logic */
1125
- config->vinst_ctrl |= BIT(9);
11261127 spin_unlock(&drvdata->spinlock);
11271128 return size;
11281129 }
....@@ -1237,6 +1238,131 @@
12371238 return size;
12381239 }
12391240 static DEVICE_ATTR_RW(addr_context);
1241
+
1242
+static ssize_t addr_exlevel_s_ns_show(struct device *dev,
1243
+ struct device_attribute *attr,
1244
+ char *buf)
1245
+{
1246
+ u8 idx;
1247
+ unsigned long val;
1248
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1249
+ struct etmv4_config *config = &drvdata->config;
1250
+
1251
+ spin_lock(&drvdata->spinlock);
1252
+ idx = config->addr_idx;
1253
+ val = BMVAL(config->addr_acc[idx], 8, 14);
1254
+ spin_unlock(&drvdata->spinlock);
1255
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1256
+}
1257
+
1258
+static ssize_t addr_exlevel_s_ns_store(struct device *dev,
1259
+ struct device_attribute *attr,
1260
+ const char *buf, size_t size)
1261
+{
1262
+ u8 idx;
1263
+ unsigned long val;
1264
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1265
+ struct etmv4_config *config = &drvdata->config;
1266
+
1267
+ if (kstrtoul(buf, 0, &val))
1268
+ return -EINVAL;
1269
+
1270
+ if (val & ~((GENMASK(14, 8) >> 8)))
1271
+ return -EINVAL;
1272
+
1273
+ spin_lock(&drvdata->spinlock);
1274
+ idx = config->addr_idx;
1275
+ /* clear Exlevel_ns & Exlevel_s bits[14:12, 11:8], bit[15] is res0 */
1276
+ config->addr_acc[idx] &= ~(GENMASK(14, 8));
1277
+ config->addr_acc[idx] |= (val << 8);
1278
+ spin_unlock(&drvdata->spinlock);
1279
+ return size;
1280
+}
1281
+static DEVICE_ATTR_RW(addr_exlevel_s_ns);
1282
+
1283
+static const char * const addr_type_names[] = {
1284
+ "unused",
1285
+ "single",
1286
+ "range",
1287
+ "start",
1288
+ "stop"
1289
+};
1290
+
1291
+static ssize_t addr_cmp_view_show(struct device *dev,
1292
+ struct device_attribute *attr, char *buf)
1293
+{
1294
+ u8 idx, addr_type;
1295
+ unsigned long addr_v, addr_v2, addr_ctrl;
1296
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1297
+ struct etmv4_config *config = &drvdata->config;
1298
+ int size = 0;
1299
+ bool exclude = false;
1300
+
1301
+ spin_lock(&drvdata->spinlock);
1302
+ idx = config->addr_idx;
1303
+ addr_v = config->addr_val[idx];
1304
+ addr_ctrl = config->addr_acc[idx];
1305
+ addr_type = config->addr_type[idx];
1306
+ if (addr_type == ETM_ADDR_TYPE_RANGE) {
1307
+ if (idx & 0x1) {
1308
+ idx -= 1;
1309
+ addr_v2 = addr_v;
1310
+ addr_v = config->addr_val[idx];
1311
+ } else {
1312
+ addr_v2 = config->addr_val[idx + 1];
1313
+ }
1314
+ exclude = config->viiectlr & BIT(idx / 2 + 16);
1315
+ }
1316
+ spin_unlock(&drvdata->spinlock);
1317
+ if (addr_type) {
1318
+ size = scnprintf(buf, PAGE_SIZE, "addr_cmp[%i] %s %#lx", idx,
1319
+ addr_type_names[addr_type], addr_v);
1320
+ if (addr_type == ETM_ADDR_TYPE_RANGE) {
1321
+ size += scnprintf(buf + size, PAGE_SIZE - size,
1322
+ " %#lx %s", addr_v2,
1323
+ exclude ? "exclude" : "include");
1324
+ }
1325
+ size += scnprintf(buf + size, PAGE_SIZE - size,
1326
+ " ctrl(%#lx)\n", addr_ctrl);
1327
+ } else {
1328
+ size = scnprintf(buf, PAGE_SIZE, "addr_cmp[%i] unused\n", idx);
1329
+ }
1330
+ return size;
1331
+}
1332
+static DEVICE_ATTR_RO(addr_cmp_view);
1333
+
1334
+static ssize_t vinst_pe_cmp_start_stop_show(struct device *dev,
1335
+ struct device_attribute *attr,
1336
+ char *buf)
1337
+{
1338
+ unsigned long val;
1339
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1340
+ struct etmv4_config *config = &drvdata->config;
1341
+
1342
+ if (!drvdata->nr_pe_cmp)
1343
+ return -EINVAL;
1344
+ val = config->vipcssctlr;
1345
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1346
+}
1347
+static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
1348
+ struct device_attribute *attr,
1349
+ const char *buf, size_t size)
1350
+{
1351
+ unsigned long val;
1352
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1353
+ struct etmv4_config *config = &drvdata->config;
1354
+
1355
+ if (kstrtoul(buf, 16, &val))
1356
+ return -EINVAL;
1357
+ if (!drvdata->nr_pe_cmp)
1358
+ return -EINVAL;
1359
+
1360
+ spin_lock(&drvdata->spinlock);
1361
+ config->vipcssctlr = val;
1362
+ spin_unlock(&drvdata->spinlock);
1363
+ return size;
1364
+}
1365
+static DEVICE_ATTR_RW(vinst_pe_cmp_start_stop);
12401366
12411367 static ssize_t seq_idx_show(struct device *dev,
12421368 struct device_attribute *attr,
....@@ -1541,8 +1667,11 @@
15411667
15421668 if (kstrtoul(buf, 16, &val))
15431669 return -EINVAL;
1544
- /* Resource selector pair 0 is always implemented and reserved */
1545
- if ((val == 0) || (val >= drvdata->nr_resource))
1670
+ /*
1671
+ * Resource selector pair 0 is always implemented and reserved,
1672
+ * namely an idx with 0 and 1 is illegal.
1673
+ */
1674
+ if ((val < 2) || (val >= 2 * drvdata->nr_resource))
15461675 return -EINVAL;
15471676
15481677 /*
....@@ -1595,6 +1724,123 @@
15951724 return size;
15961725 }
15971726 static DEVICE_ATTR_RW(res_ctrl);
1727
+
1728
+static ssize_t sshot_idx_show(struct device *dev,
1729
+ struct device_attribute *attr, char *buf)
1730
+{
1731
+ unsigned long val;
1732
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1733
+ struct etmv4_config *config = &drvdata->config;
1734
+
1735
+ val = config->ss_idx;
1736
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1737
+}
1738
+
1739
+static ssize_t sshot_idx_store(struct device *dev,
1740
+ struct device_attribute *attr,
1741
+ const char *buf, size_t size)
1742
+{
1743
+ unsigned long val;
1744
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1745
+ struct etmv4_config *config = &drvdata->config;
1746
+
1747
+ if (kstrtoul(buf, 16, &val))
1748
+ return -EINVAL;
1749
+ if (val >= drvdata->nr_ss_cmp)
1750
+ return -EINVAL;
1751
+
1752
+ spin_lock(&drvdata->spinlock);
1753
+ config->ss_idx = val;
1754
+ spin_unlock(&drvdata->spinlock);
1755
+ return size;
1756
+}
1757
+static DEVICE_ATTR_RW(sshot_idx);
1758
+
1759
+static ssize_t sshot_ctrl_show(struct device *dev,
1760
+ struct device_attribute *attr,
1761
+ char *buf)
1762
+{
1763
+ unsigned long val;
1764
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1765
+ struct etmv4_config *config = &drvdata->config;
1766
+
1767
+ spin_lock(&drvdata->spinlock);
1768
+ val = config->ss_ctrl[config->ss_idx];
1769
+ spin_unlock(&drvdata->spinlock);
1770
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1771
+}
1772
+
1773
+static ssize_t sshot_ctrl_store(struct device *dev,
1774
+ struct device_attribute *attr,
1775
+ const char *buf, size_t size)
1776
+{
1777
+ u8 idx;
1778
+ unsigned long val;
1779
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1780
+ struct etmv4_config *config = &drvdata->config;
1781
+
1782
+ if (kstrtoul(buf, 16, &val))
1783
+ return -EINVAL;
1784
+
1785
+ spin_lock(&drvdata->spinlock);
1786
+ idx = config->ss_idx;
1787
+ config->ss_ctrl[idx] = val & GENMASK(24, 0);
1788
+ /* must clear bit 31 in related status register on programming */
1789
+ config->ss_status[idx] &= ~BIT(31);
1790
+ spin_unlock(&drvdata->spinlock);
1791
+ return size;
1792
+}
1793
+static DEVICE_ATTR_RW(sshot_ctrl);
1794
+
1795
+static ssize_t sshot_status_show(struct device *dev,
1796
+ struct device_attribute *attr, char *buf)
1797
+{
1798
+ unsigned long val;
1799
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1800
+ struct etmv4_config *config = &drvdata->config;
1801
+
1802
+ spin_lock(&drvdata->spinlock);
1803
+ val = config->ss_status[config->ss_idx];
1804
+ spin_unlock(&drvdata->spinlock);
1805
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1806
+}
1807
+static DEVICE_ATTR_RO(sshot_status);
1808
+
1809
+static ssize_t sshot_pe_ctrl_show(struct device *dev,
1810
+ struct device_attribute *attr,
1811
+ char *buf)
1812
+{
1813
+ unsigned long val;
1814
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1815
+ struct etmv4_config *config = &drvdata->config;
1816
+
1817
+ spin_lock(&drvdata->spinlock);
1818
+ val = config->ss_pe_cmp[config->ss_idx];
1819
+ spin_unlock(&drvdata->spinlock);
1820
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1821
+}
1822
+
1823
+static ssize_t sshot_pe_ctrl_store(struct device *dev,
1824
+ struct device_attribute *attr,
1825
+ const char *buf, size_t size)
1826
+{
1827
+ u8 idx;
1828
+ unsigned long val;
1829
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
1830
+ struct etmv4_config *config = &drvdata->config;
1831
+
1832
+ if (kstrtoul(buf, 16, &val))
1833
+ return -EINVAL;
1834
+
1835
+ spin_lock(&drvdata->spinlock);
1836
+ idx = config->ss_idx;
1837
+ config->ss_pe_cmp[idx] = val & GENMASK(7, 0);
1838
+ /* must clear bit 31 in related status register on programming */
1839
+ config->ss_status[idx] &= ~BIT(31);
1840
+ spin_unlock(&drvdata->spinlock);
1841
+ return size;
1842
+}
1843
+static DEVICE_ATTR_RW(sshot_pe_ctrl);
15981844
15991845 static ssize_t ctxid_idx_show(struct device *dev,
16001846 struct device_attribute *attr,
....@@ -1724,6 +1970,7 @@
17241970 unsigned long val1, val2, mask;
17251971 struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
17261972 struct etmv4_config *config = &drvdata->config;
1973
+ int nr_inputs;
17271974
17281975 /*
17291976 * Don't use contextID tracing if coming from a PID namespace. See
....@@ -1739,7 +1986,9 @@
17391986 */
17401987 if (!drvdata->ctxid_size || !drvdata->numcidc)
17411988 return -EINVAL;
1742
- if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
1989
+ /* one mask if <= 4 comparators, two for up to 8 */
1990
+ nr_inputs = sscanf(buf, "%lx %lx", &val1, &val2);
1991
+ if ((drvdata->numcidc > 4) && (nr_inputs != 2))
17431992 return -EINVAL;
17441993
17451994 spin_lock(&drvdata->spinlock);
....@@ -1913,6 +2162,7 @@
19132162 unsigned long val1, val2, mask;
19142163 struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
19152164 struct etmv4_config *config = &drvdata->config;
2165
+ int nr_inputs;
19162166
19172167 /*
19182168 * only implemented when vmid tracing is enabled, i.e. at least one
....@@ -1920,7 +2170,9 @@
19202170 */
19212171 if (!drvdata->vmid_size || !drvdata->numvmidc)
19222172 return -EINVAL;
1923
- if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
2173
+ /* one mask if <= 4 comparators, two for up to 8 */
2174
+ nr_inputs = sscanf(buf, "%lx %lx", &val1, &val2);
2175
+ if ((drvdata->numvmidc > 4) && (nr_inputs != 2))
19242176 return -EINVAL;
19252177
19262178 spin_lock(&drvdata->spinlock);
....@@ -2043,6 +2295,13 @@
20432295 &dev_attr_addr_stop.attr,
20442296 &dev_attr_addr_ctxtype.attr,
20452297 &dev_attr_addr_context.attr,
2298
+ &dev_attr_addr_exlevel_s_ns.attr,
2299
+ &dev_attr_addr_cmp_view.attr,
2300
+ &dev_attr_vinst_pe_cmp_start_stop.attr,
2301
+ &dev_attr_sshot_idx.attr,
2302
+ &dev_attr_sshot_ctrl.attr,
2303
+ &dev_attr_sshot_pe_ctrl.attr,
2304
+ &dev_attr_sshot_status.attr,
20462305 &dev_attr_seq_idx.attr,
20472306 &dev_attr_seq_state.attr,
20482307 &dev_attr_seq_event.attr,
....@@ -2064,7 +2323,8 @@
20642323 };
20652324
20662325 struct etmv4_reg {
2067
- void __iomem *addr;
2326
+ struct coresight_device *csdev;
2327
+ u32 offset;
20682328 u32 data;
20692329 };
20702330
....@@ -2072,15 +2332,16 @@
20722332 {
20732333 struct etmv4_reg *reg = data;
20742334
2075
- reg->data = readl_relaxed(reg->addr);
2335
+ reg->data = etm4x_relaxed_read32(&reg->csdev->access, reg->offset);
20762336 }
20772337
2078
-static u32 etmv4_cross_read(const struct device *dev, u32 offset)
2338
+static u32 etmv4_cross_read(const struct etmv4_drvdata *drvdata, u32 offset)
20792339 {
2080
- struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
20812340 struct etmv4_reg reg;
20822341
2083
- reg.addr = drvdata->base + offset;
2342
+ reg.offset = offset;
2343
+ reg.csdev = drvdata->csdev;
2344
+
20842345 /*
20852346 * smp cross call ensures the CPU will be powered up before
20862347 * accessing the ETMv4 trace core registers
....@@ -2089,72 +2350,133 @@
20892350 return reg.data;
20902351 }
20912352
2092
-#define coresight_etm4x_reg(name, offset) \
2093
- coresight_simple_reg32(struct etmv4_drvdata, name, offset)
2353
+static inline u32 coresight_etm4x_attr_to_offset(struct device_attribute *attr)
2354
+{
2355
+ struct dev_ext_attribute *eattr;
20942356
2095
-#define coresight_etm4x_cross_read(name, offset) \
2096
- coresight_simple_func(struct etmv4_drvdata, etmv4_cross_read, \
2097
- name, offset)
2357
+ eattr = container_of(attr, struct dev_ext_attribute, attr);
2358
+ return (u32)(unsigned long)eattr->var;
2359
+}
20982360
2099
-coresight_etm4x_reg(trcpdcr, TRCPDCR);
2100
-coresight_etm4x_reg(trcpdsr, TRCPDSR);
2101
-coresight_etm4x_reg(trclsr, TRCLSR);
2102
-coresight_etm4x_reg(trcauthstatus, TRCAUTHSTATUS);
2103
-coresight_etm4x_reg(trcdevid, TRCDEVID);
2104
-coresight_etm4x_reg(trcdevtype, TRCDEVTYPE);
2105
-coresight_etm4x_reg(trcpidr0, TRCPIDR0);
2106
-coresight_etm4x_reg(trcpidr1, TRCPIDR1);
2107
-coresight_etm4x_reg(trcpidr2, TRCPIDR2);
2108
-coresight_etm4x_reg(trcpidr3, TRCPIDR3);
2109
-coresight_etm4x_cross_read(trcoslsr, TRCOSLSR);
2110
-coresight_etm4x_cross_read(trcconfig, TRCCONFIGR);
2111
-coresight_etm4x_cross_read(trctraceid, TRCTRACEIDR);
2361
+static ssize_t coresight_etm4x_reg_show(struct device *dev,
2362
+ struct device_attribute *d_attr,
2363
+ char *buf)
2364
+{
2365
+ u32 val, offset;
2366
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
2367
+
2368
+ offset = coresight_etm4x_attr_to_offset(d_attr);
2369
+
2370
+ pm_runtime_get_sync(dev->parent);
2371
+ val = etmv4_cross_read(drvdata, offset);
2372
+ pm_runtime_put_sync(dev->parent);
2373
+
2374
+ return scnprintf(buf, PAGE_SIZE, "0x%x\n", val);
2375
+}
2376
+
2377
+static inline bool
2378
+etm4x_register_implemented(struct etmv4_drvdata *drvdata, u32 offset)
2379
+{
2380
+ switch (offset) {
2381
+ ETM_COMMON_SYSREG_LIST_CASES
2382
+ /*
2383
+ * Common registers to ETE & ETM4x accessible via system
2384
+ * instructions are always implemented.
2385
+ */
2386
+ return true;
2387
+
2388
+ ETM4x_ONLY_SYSREG_LIST_CASES
2389
+ /*
2390
+ * We only support etm4x and ete. So if the device is not
2391
+ * ETE, it must be ETMv4x.
2392
+ */
2393
+ return !etm4x_is_ete(drvdata);
2394
+
2395
+ ETM4x_MMAP_LIST_CASES
2396
+ /*
2397
+ * Registers accessible only via memory-mapped registers
2398
+ * must not be accessed via system instructions.
2399
+ * We cannot access the drvdata->csdev here, as this
2400
+ * function is called during the device creation, via
2401
+ * coresight_register() and the csdev is not initialized
2402
+ * until that is done. So rely on the drvdata->base to
2403
+ * detect if we have a memory mapped access.
2404
+ * Also ETE doesn't implement memory mapped access, thus
2405
+ * it is sufficient to check that we are using mmio.
2406
+ */
2407
+ return !!drvdata->base;
2408
+
2409
+ ETE_ONLY_SYSREG_LIST_CASES
2410
+ return etm4x_is_ete(drvdata);
2411
+ }
2412
+
2413
+ return false;
2414
+}
2415
+
2416
+/*
2417
+ * Hide the ETM4x registers that may not be available on the
2418
+ * hardware.
2419
+ * There are certain management registers unavailable via system
2420
+ * instructions. Make those sysfs attributes hidden on such
2421
+ * systems.
2422
+ */
2423
+static umode_t
2424
+coresight_etm4x_attr_reg_implemented(struct kobject *kobj,
2425
+ struct attribute *attr, int unused)
2426
+{
2427
+ struct device *dev = kobj_to_dev(kobj);
2428
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
2429
+ struct device_attribute *d_attr;
2430
+ u32 offset;
2431
+
2432
+ d_attr = container_of(attr, struct device_attribute, attr);
2433
+ offset = coresight_etm4x_attr_to_offset(d_attr);
2434
+
2435
+ if (etm4x_register_implemented(drvdata, offset))
2436
+ return attr->mode;
2437
+ return 0;
2438
+}
2439
+
2440
+#define coresight_etm4x_reg(name, offset) \
2441
+ &((struct dev_ext_attribute[]) { \
2442
+ { \
2443
+ __ATTR(name, 0444, coresight_etm4x_reg_show, NULL), \
2444
+ (void *)(unsigned long)offset \
2445
+ } \
2446
+ })[0].attr.attr
21122447
21132448 static struct attribute *coresight_etmv4_mgmt_attrs[] = {
2114
- &dev_attr_trcoslsr.attr,
2115
- &dev_attr_trcpdcr.attr,
2116
- &dev_attr_trcpdsr.attr,
2117
- &dev_attr_trclsr.attr,
2118
- &dev_attr_trcconfig.attr,
2119
- &dev_attr_trctraceid.attr,
2120
- &dev_attr_trcauthstatus.attr,
2121
- &dev_attr_trcdevid.attr,
2122
- &dev_attr_trcdevtype.attr,
2123
- &dev_attr_trcpidr0.attr,
2124
- &dev_attr_trcpidr1.attr,
2125
- &dev_attr_trcpidr2.attr,
2126
- &dev_attr_trcpidr3.attr,
2449
+ coresight_etm4x_reg(trcpdcr, TRCPDCR),
2450
+ coresight_etm4x_reg(trcpdsr, TRCPDSR),
2451
+ coresight_etm4x_reg(trclsr, TRCLSR),
2452
+ coresight_etm4x_reg(trcauthstatus, TRCAUTHSTATUS),
2453
+ coresight_etm4x_reg(trcdevid, TRCDEVID),
2454
+ coresight_etm4x_reg(trcdevtype, TRCDEVTYPE),
2455
+ coresight_etm4x_reg(trcpidr0, TRCPIDR0),
2456
+ coresight_etm4x_reg(trcpidr1, TRCPIDR1),
2457
+ coresight_etm4x_reg(trcpidr2, TRCPIDR2),
2458
+ coresight_etm4x_reg(trcpidr3, TRCPIDR3),
2459
+ coresight_etm4x_reg(trcoslsr, TRCOSLSR),
2460
+ coresight_etm4x_reg(trcconfig, TRCCONFIGR),
2461
+ coresight_etm4x_reg(trctraceid, TRCTRACEIDR),
2462
+ coresight_etm4x_reg(trcdevarch, TRCDEVARCH),
21272463 NULL,
21282464 };
21292465
2130
-coresight_etm4x_cross_read(trcidr0, TRCIDR0);
2131
-coresight_etm4x_cross_read(trcidr1, TRCIDR1);
2132
-coresight_etm4x_cross_read(trcidr2, TRCIDR2);
2133
-coresight_etm4x_cross_read(trcidr3, TRCIDR3);
2134
-coresight_etm4x_cross_read(trcidr4, TRCIDR4);
2135
-coresight_etm4x_cross_read(trcidr5, TRCIDR5);
2136
-/* trcidr[6,7] are reserved */
2137
-coresight_etm4x_cross_read(trcidr8, TRCIDR8);
2138
-coresight_etm4x_cross_read(trcidr9, TRCIDR9);
2139
-coresight_etm4x_cross_read(trcidr10, TRCIDR10);
2140
-coresight_etm4x_cross_read(trcidr11, TRCIDR11);
2141
-coresight_etm4x_cross_read(trcidr12, TRCIDR12);
2142
-coresight_etm4x_cross_read(trcidr13, TRCIDR13);
2143
-
21442466 static struct attribute *coresight_etmv4_trcidr_attrs[] = {
2145
- &dev_attr_trcidr0.attr,
2146
- &dev_attr_trcidr1.attr,
2147
- &dev_attr_trcidr2.attr,
2148
- &dev_attr_trcidr3.attr,
2149
- &dev_attr_trcidr4.attr,
2150
- &dev_attr_trcidr5.attr,
2467
+ coresight_etm4x_reg(trcidr0, TRCIDR0),
2468
+ coresight_etm4x_reg(trcidr1, TRCIDR1),
2469
+ coresight_etm4x_reg(trcidr2, TRCIDR2),
2470
+ coresight_etm4x_reg(trcidr3, TRCIDR3),
2471
+ coresight_etm4x_reg(trcidr4, TRCIDR4),
2472
+ coresight_etm4x_reg(trcidr5, TRCIDR5),
21512473 /* trcidr[6,7] are reserved */
2152
- &dev_attr_trcidr8.attr,
2153
- &dev_attr_trcidr9.attr,
2154
- &dev_attr_trcidr10.attr,
2155
- &dev_attr_trcidr11.attr,
2156
- &dev_attr_trcidr12.attr,
2157
- &dev_attr_trcidr13.attr,
2474
+ coresight_etm4x_reg(trcidr8, TRCIDR8),
2475
+ coresight_etm4x_reg(trcidr9, TRCIDR9),
2476
+ coresight_etm4x_reg(trcidr10, TRCIDR10),
2477
+ coresight_etm4x_reg(trcidr11, TRCIDR11),
2478
+ coresight_etm4x_reg(trcidr12, TRCIDR12),
2479
+ coresight_etm4x_reg(trcidr13, TRCIDR13),
21582480 NULL,
21592481 };
21602482
....@@ -2163,6 +2485,7 @@
21632485 };
21642486
21652487 static const struct attribute_group coresight_etmv4_mgmt_group = {
2488
+ .is_visible = coresight_etm4x_attr_reg_implemented,
21662489 .attrs = coresight_etmv4_mgmt_attrs,
21672490 .name = "mgmt",
21682491 };