Differing default states set on driver init / perf init and as a result
of a sysfs reset.
The ETMv4 can be programmed to trace the entire instruction address range
without the need to use address comparator filter resources.
(Described in the ETMv4.x technical reference manual)
sysfs reset was using this method, perf and default driver init were setup
with an address range comparator for the entire address range.
The perf / driver init has been altered to use the method without needing
any comparator address hardware.
Minor adjustment to the vinst_ctrl register initialisation to ensure
correct zero initialisation.
Applies to Linux 5.7-rc1, tested on Juno-r1 and DB410c platforms.
Signed-off-by: Mike Leach <mike.leach(a)linaro.org>
---
.../coresight/coresight-etm4x-sysfs.c | 2 +-
drivers/hwtracing/coresight/coresight-etm4x.c | 23 +++++--------------
2 files changed, 7 insertions(+), 18 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index ce41482431f9..b673e738bc9a 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -205,7 +205,7 @@ static ssize_t reset_store(struct device *dev,
* started state. ARM recommends start-stop logic is set before
* each trace run.
*/
- config->vinst_ctrl |= BIT(0);
+ config->vinst_ctrl = BIT(0);
if (drvdata->nr_addr_cmp == true) {
config->mode |= ETM_MODE_VIEWINST_STARTSTOP;
/* SSSTATUS, bit[9] */
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index a90d757f7043..58ae5498ecf1 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -791,7 +791,7 @@ static void etm4_set_default_config(struct etmv4_config *config)
config->ts_ctrl = 0x0;
/* TRCVICTLR::EVENT = 0x01, select the always on logic */
- config->vinst_ctrl |= BIT(0);
+ config->vinst_ctrl = BIT(0);
}
static u64 etm4_get_ns_access_type(struct etmv4_config *config)
@@ -894,17 +894,8 @@ static void etm4_set_start_stop_filter(struct etmv4_config *config,
static void etm4_set_default_filter(struct etmv4_config *config)
{
- u64 start, stop;
-
- /*
- * Configure address range comparator '0' to encompass all
- * possible addresses.
- */
- start = 0x0;
- stop = ~0x0;
-
- etm4_set_comparator_filter(config, start, stop,
- ETM_DEFAULT_ADDR_COMP);
+ /* Trace everything 'default' filter achieved by no filtering */
+ config->viiectlr = 0x0;
/*
* TRCVICTLR::SSSTATUS == 1, the start-stop logic is
@@ -925,11 +916,9 @@ static void etm4_set_default(struct etmv4_config *config)
/*
* Make default initialisation trace everything
*
- * Select the "always true" resource selector on the
- * "Enablign Event" line and configure address range comparator
- * '0' to trace all the possible address range. From there
- * configure the "include/exclude" engine to include address
- * range comparator '0'.
+ * This is done by a minimum default config sufficient to enable
+ * full instruction trace - with a default filter for trace all
+ * achieved by having no filtering.
*/
etm4_set_default_config(config);
etm4_set_default_filter(config);
--
2.17.1
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier(a)linaro.org>
Cc: Mike Leach <mike.leach(a)linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan(a)codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan(a)codeaurora.org>
Tested-by: Stephen Boyd <swboyd(a)chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose(a)arm.com>
---
Changes since v1:
- Rebased onto Mathieu's coresight/next tree.
- Added comments to explain the input port tracking
---
.../hwtracing/coresight/coresight-platform.c | 85 +++++++++++++------
drivers/hwtracing/coresight/coresight.c | 7 +-
include/linux/coresight.h | 10 ++-
3 files changed, 72 insertions(+), 30 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c
index 4b78e1ac5285..d58dcd0ab514 100644
--- a/drivers/hwtracing/coresight/coresight-platform.c
+++ b/drivers/hwtracing/coresight/coresight-platform.c
@@ -87,6 +87,7 @@ static void of_coresight_get_ports_legacy(const struct device_node *node,
int *nr_inport, int *nr_outport)
{
struct device_node *ep = NULL;
+ struct of_endpoint endpoint;
int in = 0, out = 0;
do {
@@ -94,10 +95,16 @@ static void of_coresight_get_ports_legacy(const struct device_node *node,
if (!ep)
break;
- if (of_coresight_legacy_ep_is_input(ep))
- in++;
- else
- out++;
+ if (of_graph_parse_endpoint(ep, &endpoint))
+ continue;
+
+ if (of_coresight_legacy_ep_is_input(ep)) {
+ in = (endpoint.port + 1 > in) ?
+ endpoint.port + 1 : in;
+ } else {
+ out = (endpoint.port + 1) > out ?
+ endpoint.port + 1 : out;
+ }
} while (ep);
@@ -137,9 +144,16 @@ of_coresight_count_ports(struct device_node *port_parent)
{
int i = 0;
struct device_node *ep = NULL;
+ struct of_endpoint endpoint;
+
+ while ((ep = of_graph_get_next_endpoint(port_parent, ep))) {
+ /* Defer error handling to parsing */
+ if (of_graph_parse_endpoint(ep, &endpoint))
+ continue;
+ if (endpoint.port + 1 > i)
+ i = endpoint.port + 1;
+ }
- while ((ep = of_graph_get_next_endpoint(port_parent, ep)))
- i++;
return i;
}
@@ -191,14 +205,12 @@ static int of_coresight_get_cpu(struct device *dev)
* Parses the local port, remote device name and the remote port.
*
* Returns :
- * 1 - If the parsing is successful and a connection record
- * was created for an output connection.
* 0 - If the parsing completed without any fatal errors.
* -Errno - Fatal error, abort the scanning.
*/
static int of_coresight_parse_endpoint(struct device *dev,
struct device_node *ep,
- struct coresight_connection *conn)
+ struct coresight_platform_data *pdata)
{
int ret = 0;
struct of_endpoint endpoint, rendpoint;
@@ -206,6 +218,7 @@ static int of_coresight_parse_endpoint(struct device *dev,
struct device_node *rep = NULL;
struct device *rdev = NULL;
struct fwnode_handle *rdev_fwnode;
+ struct coresight_connection *conn;
do {
/* Parse the local port details */
@@ -232,6 +245,13 @@ static int of_coresight_parse_endpoint(struct device *dev,
break;
}
+ conn = &pdata->conns[endpoint.port];
+ if (conn->child_fwnode) {
+ dev_warn(dev, "Duplicate output port %d\n",
+ endpoint.port);
+ ret = -EINVAL;
+ break;
+ }
conn->outport = endpoint.port;
/*
* Hold the refcount to the target device. This could be
@@ -244,7 +264,6 @@ static int of_coresight_parse_endpoint(struct device *dev,
conn->child_fwnode = fwnode_handle_get(rdev_fwnode);
conn->child_port = rendpoint.port;
/* Connection record updated */
- ret = 1;
} while (0);
of_node_put(rparent);
@@ -258,7 +277,6 @@ static int of_get_coresight_platform_data(struct device *dev,
struct coresight_platform_data *pdata)
{
int ret = 0;
- struct coresight_connection *conn;
struct device_node *ep = NULL;
const struct device_node *parent = NULL;
bool legacy_binding = false;
@@ -287,8 +305,6 @@ static int of_get_coresight_platform_data(struct device *dev,
dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n");
}
- conn = pdata->conns;
-
/* Iterate through each output port to discover topology */
while ((ep = of_graph_get_next_endpoint(parent, ep))) {
/*
@@ -300,15 +316,9 @@ static int of_get_coresight_platform_data(struct device *dev,
if (legacy_binding && of_coresight_legacy_ep_is_input(ep))
continue;
- ret = of_coresight_parse_endpoint(dev, ep, conn);
- switch (ret) {
- case 1:
- conn++; /* Fall through */
- case 0:
- break;
- default:
+ ret = of_coresight_parse_endpoint(dev, ep, pdata);
+ if (ret)
return ret;
- }
}
return 0;
@@ -647,6 +657,16 @@ static int acpi_coresight_parse_link(struct acpi_device *adev,
* coresight_remove_match().
*/
conn->child_fwnode = fwnode_handle_get(&r_adev->fwnode);
+ } else if (dir == ACPI_CORESIGHT_LINK_SLAVE) {
+ /*
+ * We are only interested in the port number
+ * for the input ports at this component.
+ * Store the port number in child_port.
+ */
+ conn->child_port = fields[0].integer.value;
+ } else {
+ /* Invalid direction */
+ return -EINVAL;
}
return dir;
@@ -692,10 +712,20 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
return dir;
if (dir == ACPI_CORESIGHT_LINK_MASTER) {
- pdata->nr_outport++;
+ if (ptr->outport > pdata->nr_outport)
+ pdata->nr_outport = ptr->outport;
ptr++;
} else {
- pdata->nr_inport++;
+ WARN_ON(pdata->nr_inport == ptr->child_port);
+ /*
+ * We do not track input port connections for a device.
+ * However we need the highest port number described,
+ * which can be recorded now and reuse this connection
+ * record for an output connection. Hence, do not move
+ * the ptr for input connections
+ */
+ if (ptr->child_port > pdata->nr_inport)
+ pdata->nr_inport = ptr->child_port;
}
}
@@ -704,8 +734,13 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
return rc;
/* Copy the connection information to the final location */
- for (i = 0; i < pdata->nr_outport; i++)
- pdata->conns[i] = conns[i];
+ for (i = 0; conns + i < ptr; i++) {
+ int port = conns[i].outport;
+
+ /* Duplicate output port */
+ WARN_ON(pdata->conns[port].child_fwnode);
+ pdata->conns[port] = conns[i];
+ }
devm_kfree(&adev->dev, conns);
return 0;
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 4f10cfa9dc18..f3efbb3b2b4d 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -1053,6 +1053,9 @@ static int coresight_orphan_match(struct device *dev, void *data)
for (i = 0; i < i_csdev->pdata->nr_outport; i++) {
conn = &i_csdev->pdata->conns[i];
+ /* Skip the port if FW doesn't describe it */
+ if (!conn->child_fwnode)
+ continue;
/* We have found at least one orphan connection */
if (conn->child_dev == NULL) {
/* Does it match this newly added device? */
@@ -1091,6 +1094,8 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev)
for (i = 0; i < csdev->pdata->nr_outport; i++) {
struct coresight_connection *conn = &csdev->pdata->conns[i];
+ if (!conn->child_fwnode)
+ continue;
conn->child_dev =
coresight_find_csdev_by_fwnode(conn->child_fwnode);
if (conn->child_dev) {
@@ -1126,7 +1131,7 @@ static int coresight_remove_match(struct device *dev, void *data)
for (i = 0; i < iterator->pdata->nr_outport; i++) {
conn = &iterator->pdata->conns[i];
- if (conn->child_dev == NULL)
+ if (conn->child_dev == NULL || conn->child_fwnode == NULL)
continue;
if (csdev->dev.fwnode == conn->child_fwnode) {
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index ccd17304d7bd..e3e9f0e3a878 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -100,10 +100,12 @@ union coresight_dev_subtype {
};
/**
- * struct coresight_platform_data - data harvested from the DT specification
- * @nr_inport: number of input ports for this component.
- * @nr_outport: number of output ports for this component.
- * @conns: Array of nr_outport connections from this component
+ * struct coresight_platform_data - data harvested from the firmware
+ * specification.
+ *
+ * @nr_inport: Number of elements for the input connections.
+ * @nr_outport: Number of elements for the output connections.
+ * @conns: Sparse array of nr_outport connections from this component.
*/
struct coresight_platform_data {
int nr_inport;
--
2.24.1
Hi,
I wanted to reach out to you about the urgent delivery of PPE kits.
*We are FDA approved importer and have FDA approved supply for PPE kits and
can deliver most of the items within 10-14 days.*
- KN95 Mask
- 3Ply Mask
- Isolated Gowns
- Hazmat Suits
- Goggles
- Gloves
- Contactless Thermometer
- Face Shield
- Swabs
- Hand Sanitizer ( Sea Freight only)
- Rapid Test Kits (FOB China only)
*Please check our website:*
https://ppekit.online/Personal-Protective-Equipment
*For Catalogs with a lot of products and information please check:*
https://ppekit.online/supply
Reach out to us anytime on our toll-free number 855 525 2642
We have offices in the USA, U.K., Australia and we can ship your PPE
worldwide.
*We have delivered millions of pieces during COVID-19*
Thank you,
--
Andrew FB - Director of Marketing
The Dioz Group of Companies - Emergencyessentials
Office in the UK, USA, Australia.
HQ: 8730 Wilshire Blvd, Penthouse
Beverly Hills, CA 90211
Email:info@ppekits.us
Free Call: 855 525 2642
You may unsubscribe
<http://ec2-52-26-194-35.us-west-2.compute.amazonaws.com/x/u?u=8fbb1243-9817…>
to stop receiving our emails.
On some systems the firmware may not describe all the ports
connected to a component (e.g, for security reasons). This
could be especially problematic for "funnels" where we could
end up in modifying memory beyond the allocated space for
refcounts.
e.g, for a funnel with input ports listed 0, 3, 5, nr_inport = 3.
However the we could access refcnts[5] while checking for
references, like :
[ 526.110401] ==================================================================
[ 526.117988] BUG: KASAN: slab-out-of-bounds in funnel_enable+0x54/0x1b0
[ 526.124706] Read of size 4 at addr ffffff8135f9549c by task bash/1114
[ 526.131324]
[ 526.132886] CPU: 3 PID: 1114 Comm: bash Tainted: G S 5.4.25 #232
[ 526.140397] Hardware name: Qualcomm Technologies, Inc. SC7180 IDP (DT)
[ 526.147113] Call trace:
[ 526.149653] dump_backtrace+0x0/0x188
[ 526.153431] show_stack+0x20/0x2c
[ 526.156852] dump_stack+0xdc/0x144
[ 526.160370] print_address_description+0x3c/0x494
[ 526.165211] __kasan_report+0x144/0x168
[ 526.169170] kasan_report+0x10/0x18
[ 526.172769] check_memory_region+0x1a4/0x1b4
[ 526.177164] __kasan_check_read+0x18/0x24
[ 526.181292] funnel_enable+0x54/0x1b0
[ 526.185072] coresight_enable_path+0x104/0x198
[ 526.189649] coresight_enable+0x118/0x26c
...
[ 526.237782] Allocated by task 280:
[ 526.241298] __kasan_kmalloc+0xf0/0x1ac
[ 526.245249] kasan_kmalloc+0xc/0x14
[ 526.248849] __kmalloc+0x28c/0x3b4
[ 526.252361] coresight_register+0x88/0x250
[ 526.256587] funnel_probe+0x15c/0x228
[ 526.260365] dynamic_funnel_probe+0x20/0x2c
[ 526.264679] amba_probe+0xbc/0x158
[ 526.268193] really_probe+0x144/0x408
[ 526.271970] driver_probe_device+0x70/0x140
...
[ 526.316810]
[ 526.318364] Freed by task 0:
[ 526.321344] (stack is not available)
[ 526.325024]
[ 526.326580] The buggy address belongs to the object at ffffff8135f95480
[ 526.326580] which belongs to the cache kmalloc-128 of size 128
[ 526.339439] The buggy address is located 28 bytes inside of
[ 526.339439] 128-byte region [ffffff8135f95480, ffffff8135f95500)
[ 526.351399] The buggy address belongs to the page:
[ 526.356342] page:ffffffff04b7e500 refcount:1 mapcount:0 mapping:ffffff814b00c380 index:0x0 compound_mapcount: 0
[ 526.366711] flags: 0x4000000000010200(slab|head)
[ 526.371475] raw: 4000000000010200 ffffffff05034008 ffffffff0501eb08 ffffff814b00c380
[ 526.379435] raw: 0000000000000000 0000000000190019 00000001ffffffff 0000000000000000
[ 526.387393] page dumped because: kasan: bad access detected
[ 526.393128]
[ 526.394681] Memory state around the buggy address:
[ 526.399619] ffffff8135f95380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.407046] ffffff8135f95400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.414473] >ffffff8135f95480: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.421900] ^
[ 526.426029] ffffff8135f95500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.433456] ffffff8135f95580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 526.440883] ==================================================================
To keep the code simple, we now track the maximum number of
possible input/output connections to/from this component
@ nr_inport and nr_outport in platform_data, respectively.
Thus the output connections could be sparse and code is
adjusted to skip the unspecified connections.
Cc: Mathieu Poirier <mathieu.poirier(a)linaro.org>
Cc: Mike Leach <mike.leach(a)linaro.org>
Reported-by: Sai Prakash Ranjan <saiprakash.ranjan(a)codeaurora.org>
Tested-by: Sai Prakash Ranjan <saiprakash.ranjan(a)codeaurora.org>
Tested-by: Stephen Boyd <swboyd(a)chromium.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose(a)arm.com>
---
.../hwtracing/coresight/coresight-platform.c | 74 ++++++++++++-------
drivers/hwtracing/coresight/coresight.c | 8 +-
include/linux/coresight.h | 10 ++-
3 files changed, 62 insertions(+), 30 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c
index 3c5bee429105..c57373b49b42 100644
--- a/drivers/hwtracing/coresight/coresight-platform.c
+++ b/drivers/hwtracing/coresight/coresight-platform.c
@@ -67,6 +67,7 @@ static void of_coresight_get_ports_legacy(const struct device_node *node,
int *nr_inport, int *nr_outport)
{
struct device_node *ep = NULL;
+ struct of_endpoint endpoint;
int in = 0, out = 0;
do {
@@ -74,10 +75,16 @@ static void of_coresight_get_ports_legacy(const struct device_node *node,
if (!ep)
break;
- if (of_coresight_legacy_ep_is_input(ep))
- in++;
- else
- out++;
+ if (of_graph_parse_endpoint(ep, &endpoint))
+ continue;
+
+ if (of_coresight_legacy_ep_is_input(ep)) {
+ in = (endpoint.port + 1 > in) ?
+ endpoint.port + 1 : in;
+ } else {
+ out = (endpoint.port + 1) > out ?
+ endpoint.port + 1 : out;
+ }
} while (ep);
@@ -117,9 +124,16 @@ of_coresight_count_ports(struct device_node *port_parent)
{
int i = 0;
struct device_node *ep = NULL;
+ struct of_endpoint endpoint;
+
+ while ((ep = of_graph_get_next_endpoint(port_parent, ep))) {
+ /* Defer error handling to parsing */
+ if (of_graph_parse_endpoint(ep, &endpoint))
+ continue;
+ if (endpoint.port + 1 > i)
+ i = endpoint.port + 1;
+ }
- while ((ep = of_graph_get_next_endpoint(port_parent, ep)))
- i++;
return i;
}
@@ -171,14 +185,12 @@ static int of_coresight_get_cpu(struct device *dev)
* Parses the local port, remote device name and the remote port.
*
* Returns :
- * 1 - If the parsing is successful and a connection record
- * was created for an output connection.
* 0 - If the parsing completed without any fatal errors.
* -Errno - Fatal error, abort the scanning.
*/
static int of_coresight_parse_endpoint(struct device *dev,
struct device_node *ep,
- struct coresight_connection *conn)
+ struct coresight_platform_data *pdata)
{
int ret = 0;
struct of_endpoint endpoint, rendpoint;
@@ -186,6 +198,7 @@ static int of_coresight_parse_endpoint(struct device *dev,
struct device_node *rep = NULL;
struct device *rdev = NULL;
struct fwnode_handle *rdev_fwnode;
+ struct coresight_connection *conn;
do {
/* Parse the local port details */
@@ -212,6 +225,13 @@ static int of_coresight_parse_endpoint(struct device *dev,
break;
}
+ conn = &pdata->conns[endpoint.port];
+ if (conn->child_fwnode) {
+ dev_warn(dev, "Duplicate output port %d\n",
+ endpoint.port);
+ ret = -EINVAL;
+ break;
+ }
conn->outport = endpoint.port;
/*
* Hold the refcount to the target device. This could be
@@ -224,7 +244,6 @@ static int of_coresight_parse_endpoint(struct device *dev,
conn->child_fwnode = fwnode_handle_get(rdev_fwnode);
conn->child_port = rendpoint.port;
/* Connection record updated */
- ret = 1;
} while (0);
of_node_put(rparent);
@@ -238,7 +257,6 @@ static int of_get_coresight_platform_data(struct device *dev,
struct coresight_platform_data *pdata)
{
int ret = 0;
- struct coresight_connection *conn;
struct device_node *ep = NULL;
const struct device_node *parent = NULL;
bool legacy_binding = false;
@@ -267,8 +285,6 @@ static int of_get_coresight_platform_data(struct device *dev,
dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n");
}
- conn = pdata->conns;
-
/* Iterate through each output port to discover topology */
while ((ep = of_graph_get_next_endpoint(parent, ep))) {
/*
@@ -280,15 +296,9 @@ static int of_get_coresight_platform_data(struct device *dev,
if (legacy_binding && of_coresight_legacy_ep_is_input(ep))
continue;
- ret = of_coresight_parse_endpoint(dev, ep, conn);
- switch (ret) {
- case 1:
- conn++; /* Fall through */
- case 0:
- break;
- default:
+ ret = of_coresight_parse_endpoint(dev, ep, pdata);
+ if (ret)
return ret;
- }
}
return 0;
@@ -627,6 +637,11 @@ static int acpi_coresight_parse_link(struct acpi_device *adev,
* coresight_remove_match().
*/
conn->child_fwnode = fwnode_handle_get(&r_adev->fwnode);
+ } else if (dir == ACPI_CORESIGHT_LINK_SLAVE) {
+ conn->child_port = fields[0].integer.value;
+ } else {
+ /* Invalid direction */
+ return -EINVAL;
}
return dir;
@@ -672,10 +687,14 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
return dir;
if (dir == ACPI_CORESIGHT_LINK_MASTER) {
- pdata->nr_outport++;
+ if (ptr->outport > pdata->nr_outport)
+ pdata->nr_outport = ptr->outport;
ptr++;
} else {
- pdata->nr_inport++;
+ WARN_ON(pdata->nr_inport == ptr->child_port);
+ /* Do not move the ptr for input connections */
+ if (ptr->child_port > pdata->nr_inport)
+ pdata->nr_inport = ptr->child_port;
}
}
@@ -684,8 +703,13 @@ static int acpi_coresight_parse_graph(struct acpi_device *adev,
return rc;
/* Copy the connection information to the final location */
- for (i = 0; i < pdata->nr_outport; i++)
- pdata->conns[i] = conns[i];
+ for (i = 0; conns + i < ptr; i++) {
+ int port = conns[i].outport;
+
+ /* Duplicate output port */
+ WARN_ON(pdata->conns[port].child_fwnode);
+ pdata->conns[port] = conns[i];
+ }
devm_kfree(&adev->dev, conns);
return 0;
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index ef20f74c85fa..f07bc0a7ab88 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -990,6 +990,9 @@ static int coresight_orphan_match(struct device *dev, void *data)
for (i = 0; i < i_csdev->pdata->nr_outport; i++) {
conn = &i_csdev->pdata->conns[i];
+ /* Skip the port if FW doesn't describe it */
+ if (!conn->child_fwnode)
+ continue;
/* We have found at least one orphan connection */
if (conn->child_dev == NULL) {
/* Does it match this newly added device? */
@@ -1029,6 +1032,9 @@ static void coresight_fixup_device_conns(struct coresight_device *csdev)
struct coresight_connection *conn = &csdev->pdata->conns[i];
struct device *dev = NULL;
+ if (!conn->child_fwnode)
+ continue;
+
dev = bus_find_device_by_fwnode(&coresight_bustype, conn->child_fwnode);
if (dev) {
conn->child_dev = to_coresight_device(dev);
@@ -1061,7 +1067,7 @@ static int coresight_remove_match(struct device *dev, void *data)
for (i = 0; i < iterator->pdata->nr_outport; i++) {
conn = &iterator->pdata->conns[i];
- if (conn->child_dev == NULL)
+ if (conn->child_dev == NULL || conn->child_fwnode == NULL)
continue;
if (csdev->dev.fwnode == conn->child_fwnode) {
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 44e552de419c..7f8d2b39aee2 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -90,10 +90,12 @@ union coresight_dev_subtype {
};
/**
- * struct coresight_platform_data - data harvested from the DT specification
- * @nr_inport: number of input ports for this component.
- * @nr_outport: number of output ports for this component.
- * @conns: Array of nr_outport connections from this component
+ * struct coresight_platform_data - data harvested from the firmware
+ * specification.
+ *
+ * @nr_inport: Number of elements for the input connections.
+ * @nr_outport: Number of elements for the output connections.
+ * @conns: Sparse arrray of nr_outport connections from this component.
*/
struct coresight_platform_data {
int nr_inport;
--
2.24.1
Hi Mathieu and Suzuki,
I'm working a patch set to support building coresight drivers as
loadable modules. The main gap is handling dynamicly unload module when
there's some enabled coresight path.
I tried to disable all the enabled coresight paths when device driver
calls coresight_unregister() and free that path. In this case, there
will be no access to the structures that have been freed after removing
the device.
This works fine with sysfs use case. I use one script to unload/load
coresight module continuously and another script to enable/disable
coresight sink/source continuously. There're no Kernel panic.
I'm not really familiar with perf side since most of my work is on sysfs
side. I'd like to know your opinion whether we can do similar thing on
perf use case.Base on my limit understanding on perf etm module, I have
some basic ideas.
1.Record the new perf event to a global list.
2.Record enabled perf event to per_cpu variable since there's only one
enabled event on one CPU.
3.Make a call from coresight_unregister() to perf_etm to clean up.
4.Go through enabled perf events and disable them when device on their
path is removed.
5.Go through global events list and remove all the events with removed
device on their path.
I'm seeking for the correct way to disable perf event and remove them
from etm_perf driver.I'm also thinking about the correct lock to avoid
racing.
Thanks,
Tingwei
This patch updates the documentation to better capture
the current status with the latest kernel releases and
defines new scripts for controlling strobing accordingly.
Signed-off-by: Andrea Brunato <andrea.brunato(a)arm.com>
---
HOWTO.md | 54 +++++++++---------
decoder/tests/auto-fdo/autofdo.md | 73 +++++++++++++++++++------
decoder/tests/auto-fdo/record.sh | 68 -----------------------
decoder/tests/auto-fdo/set_strobing.sh | 29 ++++++++++
decoder/tests/auto-fdo/show_strobing.sh | 6 ++
5 files changed, 115 insertions(+), 115 deletions(-)
delete mode 100644 decoder/tests/auto-fdo/record.sh
create mode 100755 decoder/tests/auto-fdo/set_strobing.sh
create mode 100755 decoder/tests/auto-fdo/show_strobing.sh
diff --git a/HOWTO.md b/HOWTO.md
index b16294a..ebf44eb 100644
--- a/HOWTO.md
+++ b/HOWTO.md
@@ -6,35 +6,31 @@ HOWTO - using the library with perf {#howto_perf}
This HOWTO explains how to use the perf cmd line tools and the openCSD
library to collect and extract program flow traces generated by the
CoreSight IP blocks on a Linux system. The examples have been generated using
-an aarch64 Juno-r0 platform. All information is considered accurate and tested
-using the latest version of the library and the `master` branch on the
-[perf-opencsd github repository][1].
+an aarch64 Juno-r0 platform.
On Target Trace Acquisition - Perf Record
-----------------------------------------
-All the enhancement to the Perf tools that support the new `cs_etm` pmu have
-not been upstreamed yet. To get the required functionality branch
-`perf-opencsd-master` needs to be downloaded to the target system where
-traces are to be collected. This branch is a vanilla upstream kernel
-supplemented with modifications to the CoreSight framework and drivers to be
-usable by the Perf core. The remaining out of tree patches are being
-upstreamed incrementally.
-
-From there compiling the perf tools with `make -C tools/perf CORESIGHT=1` will
-yield a `perf` executable that will support CoreSight trace collection. Note
-that if traces are to be decompressed *off* target, there is no need to download
+
+Compile the perf tool from the same kernel source code version you are using,
+with `make -C tools/perf`.
+This will yield a `perf` executable that will support CoreSight trace collection.
+Note that if traces are to be decompressed *off* target, there is no need to download
and compile the openCSD library (on the target).
+If you are instead planning to use perf to record and decode the trace on the target,
+compile the perf tool linking against the openCSD library, in the following way:
+`make -C tools/perf VF=1 CORESIGHT=1`
+
+
Before launching a trace run a sink that will collect trace data needs to be
identified. All CoreSight blocks identified by the framework are registed in
sysFS:
linaro@linaro-nano:~$ ls /sys/bus/coresight/devices/
- 20010000.etf 20040000.main_funnel 22040000.etm 22140000.etm
- 230c0000.A53_funnel 23240000.etm replicator@20020000 20030000.tpiu
- 20070000.etr 220c0000.A57_funnel 23040000.etm 23140000.etm 23340000.etm
+ etm0 etm2 etm4 etm6 funnel0 funnel2 funnel4 stm0 tmc_etr0
+ etm1 etm3 etm5 etm7 funnel1 funnel3 replicator0 tmc_etf0
CoreSight blocks are listed in the device tree for a specific system and
@@ -43,7 +39,7 @@ the sink that will recieve trace data needs to be identified and given as an
option on the perf command line. Once a sink has been identify trace collection
can start. An easy and yet interesting example is the `uname` command:
- linaro@linaro-nano:~/kernel$ ./tools/perf/perf record -e cs_etm/(a)20070000.etr/ --per-thread uname
+ linaro@linaro-nano:~/kernel$ ./tools/perf/perf record -e cs_etm/@tmc_etr0/ --per-thread uname
This will generate a `perf.data` file where execution has been traced for both
user and kernel space. To narrow the field to either user or kernel space the
@@ -51,7 +47,7 @@ user and kernel space. To narrow the field to either user or kernel space the
traces to user space:
- linaro@linaro-nano:~/kernel$ ./tools/perf/perf record -vvv -e cs_etm/(a)20070000.etr/u --per-thread uname
+ linaro@linaro-nano:~/kernel$ ./tools/perf/perf record -vvv -e cs_etm/@tmc_etr0/u --per-thread uname
Problems setting modules path maps, continuing anyway...
-----------------------------------------------------------
perf_event_attr:
@@ -131,9 +127,9 @@ falls within the specified range. Any work done by the CPU outside of that
range will not be traced. Address range filters can be specified for both
user and kernel space session:
- perf record -e cs_etm/(a)20070000.etr/k --filter 'filter 0xffffff8008562d0c/0x48' --per-thread uname
+ perf record -e cs_etm/@tmc_etr0/k --filter 'filter 0xffffff8008562d0c/0x48' --per-thread uname
- perf record -e cs_etm/(a)20070000.etr/u --filter 'filter 0x72c/0x40(a)/opt/lib/libcstest.so.1.0' --per-thread ./main
+ perf record -e cs_etm/@tmc_etr0/u --filter 'filter 0x72c/0x40(a)/opt/lib/libcstest.so.1.0' --per-thread ./main
When dealing with kernel space trace addresses are typically taken in the
'System.map' file. In user space addresses are relocatable and can be
@@ -171,20 +167,20 @@ equal to the start address. Incidentally traces stop being generated when the
insruction pointer is equal to the stop address. Anything that happens between
there to events is traced:
- perf record -e cs_etm/(a)20070000.etr/k --filter 'start 0xffffff800856bc50,stop 0xffffff800856bcb0' --per-thread uname
+ perf record -e cs_etm/@tmc_etr0/k --filter 'start 0xffffff800856bc50,stop 0xffffff800856bcb0' --per-thread uname
- perf record -vvv -e cs_etm/(a)20070000.etr/u --filter 'start 0x72c(a)/opt/lib/libcstest.so.1.0, \
+ perf record -vvv -e cs_etm/@tmc_etr0/u --filter 'start 0x72c(a)/opt/lib/libcstest.so.1.0, \
stop 0x40082c@/home/linaro/main' \
- --per-thread ./main
+ --per-thread ./main
**Limitation on address filters:**
The only limitation on address filters is the amount of address comparator
found on an implementation and the mutual exclusion between range and
start stop filters. As such the following example would _not_ work:
- perf record -e cs_etm/(a)20070000.etr/k --filter 'start 0xffffff800856bc50,stop 0xffffff800856bcb0, \ // start/stop
+ perf record -e cs_etm/@tmc_etr0/k --filter 'start 0xffffff800856bc50,stop 0xffffff800856bcb0, \ // start/stop
filter 0x72c/0x40(a)/opt/lib/libcstest.so.1.0' \ // address range
- --per-thread uname
+ --per-thread uname
Additional Trace Options
------------------------
@@ -198,7 +194,7 @@ Presently this threshold is fixed at 256 cycles for `perf record`.
Command line options in `perf record` to use these features are part of the options for the `cs_etm` event:
- perf record -e cs_etm/timestamp,cycacc,(a)20070000.etr/ --per-thread uname
+ perf record -e cs_etm/timestamp,cycacc,@tmc_etr0/ --per-thread uname
At current version, `perf record` and `perf script` do not use this additional information.
@@ -248,7 +244,7 @@ The openCSD library is not part of the perf tools. It is available on
[github][1] and needs to be compiled before the perf tools. Checkout the
required branch/tag version into a local directory.
- linaro@t430:~/linaro/coresight$ git clone -b v0.8 https://github.com/Linaro/OpenCSD.git my-opencsd
+ linaro@t430:~/linaro/coresight$ git clone https://github.com/Linaro/OpenCSD.git my-opencsd
Cloning into 'OpenCSD'...
remote: Counting objects: 2063, done.
remote: Total 2063 (delta 0), reused 0 (delta 0), pack-reused 2063
@@ -629,7 +625,7 @@ Best regards,
*The Linaro CoreSight Team*
--------------------------------------
-[1]: https://github.com/Linaro/perf-opencsd "perf-opencsd Github"
+[1]: https://github.com/Linaro/OpenCSD
[2]: http://people.linaro.org/~mathieu.poirier/openCSD/uname.v4.user.sept20.tgz
diff --git a/decoder/tests/auto-fdo/autofdo.md b/decoder/tests/auto-fdo/autofdo.md
index b1f2241..d7d37b1 100644
--- a/decoder/tests/auto-fdo/autofdo.md
+++ b/decoder/tests/auto-fdo/autofdo.md
@@ -99,6 +99,8 @@ You can include these backports in your kernel by either merging the
appropriate branch using git or generating patches (using `git
format-patch`).
+For 5.5 based kernel, the only patch which needs to be applied is the one enabling strobing - etm4x: `Enable strobing of ETM`.
+
For 4.9 based kernels, use the `coresight-4.9-etr-etm_strobe` branch:
```
@@ -129,7 +131,7 @@ git am /output/dir/*.patch # or patch -p1 /output/dir/*.patch if not using git
The CoreSight trace drivers must also be enabled in the kernel
configuration. This can be done using the configuration menu (`make
-menuconfig`), selecting `Kernel hacking` / `CoreSight Tracing Support` and
+menuconfig`), selecting `Kernel hacking` / `arm64 Debugging` /`CoreSight Tracing Support` and
enabling all options, or by setting the following in the configuration
file:
@@ -165,11 +167,15 @@ CoreSight devices, you should find the devices in sysfs:
```
# ls /sys/bus/coresight/devices/
-28440000.etm 28540000.etm 28640000.etm 28740000.etm
-28c03000.funnel 28c04000.etf 28c05000.replicator 28c06000.etr
-28c07000.tpiu
+etm0 etm2 etm4 etm6 funnel0 funnel2 funnel4 stm0 tmc_etr0
+etm1 etm3 etm5 etm7 funnel1 funnel3 replicator0 tmc_etf0
```
+The naming convention for etm devices can be different according to the kernel version you're using.
+For more information about the naming scheme, please check out the [Linux Kernel Documentation](https://www.kernel.org/doc/html/latest/trace/coresight/cores…
+
+If `/sys/bus/coresight/devices/` is empty, you may want to check out your Kernel configuration to make sure your .config file is including CoreSight dependencies, such as the clock.
+
### Perf tools
The perf tool is used to capture execution trace, configuring the trace
@@ -180,9 +186,12 @@ Arm recommends to use the perf version corresponding to the kernel running
on the target. This can be built from the same kernel sources with
```
-make -C tools/perf ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
+make -C tools/perf CORESIGHT=1 VF=1 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
```
+When specifying CORESIGHT=1, perf will be built using the installed OpenCSD library.
+If you are cross compiling, then additional setup is required to ensure the build process links against the correct version of the library.
+
If the post-processing (`perf inject`) of the captured data is not being
done on the target, then the OpenCSD library is not required for this build
of perf.
@@ -193,13 +202,22 @@ also be restricted to user space or kernel space with 'u' or 'k'
parameters. For example:
```
-perf record -e cs_etm/(a)28c06000.etr/u --per-thread -- /bin/ls
+perf record -e cs_etm/@tmc_etr0/u --per-thread -- /bin/ls
```
-Will record the userspace execution of '/bin/ls' into the ETR located at
-0x28c06000. Note the `--per-thread` option is required - perf currently
-only supports trace of a single thread of execution. CPU wide trace is a
-work in progresss.
+Will record the userspace execution of '/bin/ls' using tmc_etr0 as sink.
+
+## Capturing modes
+
+You can trace a single-threaded program in two different ways:
+
+1. By specifying `--per-thread`, and in this case the CoreSight subsystem will
+record only a trace relative to the given program.
+
+2. By NOT specifying `--per-thread`, and in this case CPU-wide tracing will
+be enabled. In this scenario the trace will contain both the target program trace
+and other workloads that were executing on the same CPU
+
## Processing trace and profiles
@@ -241,26 +259,42 @@ For example, a typical configuration is to use a window size of 5000 cycles
and a period of 10000 - this will collect 5000 cycles of trace every 50M
cycles. With these proof-of-concept patches, the strobe parameters are
configured via sysfs - each ETM will have `strobe_window` and
-`strobe_period` parameters in `/sys/bus/coresight/devices/NNNNNNNN.etm` and
+`strobe_period` parameters in `/sys/bus/coresight/devices/<sink>` and
these values will have to be written to each (In a future version, this
-will be integrated into the drivers and perf tool). The `record.sh`
-script in this directory [`<opencsd>/decoder/tests/auto-fdo`] automates this process.
+will be integrated into the drivers and perf tool).
+The `set_strobing.sh` script in this directory [`<opencsd>/decoder/tests/auto-fdo`] automates this process.
To collect trace from an application using ETM strobing, run:
```
-taskset -c 0 ./record.sh --strobe 5000 10000 28c06000.etr ./my_application arg1 arg2
+sudo ./set_strobing.sh 5000 10000
+perf record -e cs_etm/@tmc_etr0/u --per-thread -- <your app>"
```
-The taskset command is used to ensure the process stays on the same CPU
-during execution.
-
The raw trace can be examined using the `perf report` command:
```
perf report -D -i perf.data --stdio
```
+Perf needs to be built from your linux kernel version souce code repository against the OpenCSD library in order to be able to properly read ETM-gathered samples and post-process them.
+If running `perf report` produces an error like:
+
+```
+0x1f8 [0x268]: failed to process type: 70 [Operation not permitted]
+Error:
+failed to process sample
+```
+or
+
+```
+"file uses a more recent and unsupported ABI (8 bytes extra). incompatible file format".
+```
+
+You are probably using a perf version which is not using this library: please make sure to install this project in your system by either compiling it from [Source Code]( <https://github.com/Linaro/OpenCSD>) from v0.9.1 or later and compile perf using this library.
+Otherwise, this project is packaged for debian (install the libopencsd0, libopencsd-dev packages).
+
+
For example:
```
@@ -295,6 +329,8 @@ an embedded target). The `perf inject` command
decodes the execution trace and generates periodic instruction samples,
with branch histories:
+!! Careful: if you are using a device different than the one used to collect the profiling data,
+you'll need to run `perf buildid-cache` as described below.
```
perf inject -i perf.data -o inj.data --itrace=i100000il
```
@@ -393,7 +429,8 @@ clang -O2 -fprofile-sample-use=program.llvmprof -o program program.c
The basic commands to run an application and create a compiler profile are:
```
-taskset -c 0 ./record.sh --strobe 5000 10000 28c06000.etr ./my_application arg1 arg2
+sudo ./set_strobing.sh 5000 10000
+perf record -e cs_etm/@tmc_etr0/u --per-thread -- <your app>"
perf inject -i perf.data -o inj.data --itrace=i100000il
create_llvm_prof -binary=/path/to/binary -profile=inj.data -out=program.llvmprof
```
diff --git a/decoder/tests/auto-fdo/record.sh b/decoder/tests/auto-fdo/record.sh
deleted file mode 100644
index 16d4ba2..0000000
--- a/decoder/tests/auto-fdo/record.sh
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/sh
-
-BUFFER_ETF_A53=ec802000.etf
-BUFFER_ETF_A73=ed002000.etf
-BUFFER_ETF_SYS=ec036000.etf
-BUFFER_ETR=ec033000.etr
-
-OUT_FILE=perf.data
-
-STROBE=
-
-while :; do
- case $1 in
- --strobe)
- STROBE=y
- WINDOW=$2
- PERIOD=$3
- shift 3
- ;;
-
- *)
- break ;;
- esac
-done
-
-case $1 in
- etr)
- BUFFER=$BUFFER_ETR
- ;;
-
- etf-sys)
- BUFFER=$BUFFER_ETF_SYS
- ;;
-
- "")
- BUFFER=$BUFFER_ETR
- ;;
-
- *)
- BUFFER=$1
- ;;
-esac
-
-shift 1
-
-case $0 in
- /*) F=$0 ;;
- *) F=$(pwd)/$0 ;;
-esac
-
-SCRIPT_DIR=$(dirname $F)
-
-if [ "$STROBE" ]; then
- for e in /sys/bus/coresight/devices/*.etm/; do
- printf "%x" $WINDOW | sudo tee $e/strobe_window > /dev/null
- printf "%x" $PERIOD | sudo tee $e/strobe_period > /dev/null
- done
-fi
-
-PERF=$SCRIPT_DIR/perf
-
-export LD_LIBRARY_PATH=$SCRIPT_DIR:$LD_LIBRARY_PATH
-
-sudo LD_LIBRARY_PATH=$SCRIPT_DIR:$LD_LIBRARY_PATH $PERF record $PERF_ARGS -e cs_etm/@$BUFFER/u --per-thread "$@"
-
-sudo chown $(id -u):$(id -g) $OUT_FILE
-
-
diff --git a/decoder/tests/auto-fdo/set_strobing.sh b/decoder/tests/auto-fdo/set_strobing.sh
new file mode 100755
index 0000000..e11e62d
--- /dev/null
+++ b/decoder/tests/auto-fdo/set_strobing.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+WINDOW=$1
+PERIOD=$2
+
+if [[ -z $WINDOW ]] || [[ -z $PERIOD ]]; then
+ echo "Window or Period not specified!"
+ echo "Example usage: ./set_strobing.sh <WINDOW VALUE> <PERIOD VALUE>"
+ echo "Example usage: ./set_strobing.sh 5000 10000"
+ exit
+fi
+
+
+if [[ $EUID != 0 ]]; then
+ echo "Please run as root"
+ exit
+fi
+
+for e in /sys/bus/coresight/devices/etm*/; do
+ printf "%x" $WINDOW | tee $e/strobe_window > /dev/null
+ printf "%x" $PERIOD | tee $e/strobe_period > /dev/null
+ echo "Strobing period for $e set to $((`cat $e/strobe_period`))"
+ echo "Strobing window for $e set to $((`cat $e/strobe_window`))"
+done
+
+## Shows the user a simple usage example
+echo ">> Done! <<"
+echo "You can now run perf to trace your application, for example:"
+echo "perf record -e cs_etm/@tmc_etr0/u -- <your app>"
diff --git a/decoder/tests/auto-fdo/show_strobing.sh b/decoder/tests/auto-fdo/show_strobing.sh
new file mode 100755
index 0000000..d80d84c
--- /dev/null
+++ b/decoder/tests/auto-fdo/show_strobing.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+for e in /sys/bus/coresight/devices/etm*/; do
+ echo "Strobing period for $e is $((`cat $e/strobe_period`))"
+ echo "Strobing window for $e is $((`cat $e/strobe_window`))"
+done
--
2.17.1
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
OpenCSD v0.14.0 is now released.
This update contains a re-work of the ETMv4 decoder to simplify,
reduce re-entancy and enable speculative tracing support.
Speculative tracing support has been verified by an architecture
development team within ARM.
Other bugfixes and minor enhancements as per the readme file.
Documentation is updated to reflect the latest versions of the kernel
drivers (5.x).
v0.15.0-dev version also released. This contains preliminary support
for Q elements.
Regards
Mike
--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK