文章目录
Coresight是一个允许调试基于ARM的SoC技术。它包括JTAG和硬件辅助跟踪的解决方案,为实时调试和收集跟踪信息提供了系统范围的解决方案。
硬件辅助跟踪在处理具有许多SoC和其他组件(如GPU和DMA引擎)的系统时变得越来越有用。ARM通过不同的组件开发了硬件辅助跟踪解决方案,每个组件在合成时添加到设计中,以满足特定的跟踪需求。组件通常分为 source、link 和 sinks,通常使用AMBA总线进行查找。
Sources 根据用户配置的跟踪场景生成表示处理器指令路径的压缩流 。stream 流经CoreSight系统(通过ATB总线)使用 links 将 the emanating source 连接到 sink(s)。Sinks充当CoreSight实施的endpoints ,要么将压缩流存储在内存缓冲区中,要么创建到外部世界的接口,在那里数据可以传输到主机,而不必担心填满板载CoreSight内存缓冲区。
即:Sinks作为最后的endpoints将压缩流存储可以选择存储在内存缓冲区(处理器自我调试)中,也可以输出给外部的trace port(外部调试器)。
典型的CoreSight系统如下所示:
(1)多个处理器:

虽然组件的目标配置是通过APB总线完成的,但所有跟踪数据都在ATB总线上带外执行。CTM提供了一种在CoreSight组件之间聚合和分发信号的方法。
CoreSight框架提供了一个中心点来表示、配置和管理平台上的CoreSight设备。第一个实施以基本跟踪功能为中心,启用ETM/PTM、funnel、replicator、TMC、TPIU和ETB等组件。未来的工作将使更复杂的IP块,如STM和CTI。
每个逻辑处理器上都与一个ETM,CTI绑定。
(2)对于单个处理器系统中的架构图如下所示:

PTM:
Program Trace Macrocell
ETM:
Embedded Trace Macrocell
STM:
System trace Macrocell
ETB:
Embedded Trace Buffer
ITM:
Instrumentation Trace Macrocell
TPIU:
Trace Port Interface Unit
TMC-ETR:
Trace Memory Controller, configured as Embedded Trace Router
TMC-ETF:
Trace Memory Controller, configured as Embedded Trace FIFO
CTI:
Cross Trigger Interface
CoreSight体系结构指定了一组组件,用于实现支持调试和跟踪信息收集的特定SoC子系统。主要组件包括:
(1)Control components:
CoreSight系统包括 Embedded Cross Trigger (ECT)控制组件,ECT包括:
• A Cross Trigger Interface (CTI):每个core都有一个CTI组件相连,CTI可以给处理器发送trigger信号,也可以接收处理器的trigger信号.
• A Cross Trigger Matrix (CTM):所有的CTI和CTM相连,因此可以实现多个CTI之间的trigger信号的相互发送与接收.
trigger通路,用于给指定的组件发送trigger信号,或者接收指定的组件的trigger信号.

(2)Trace sources(用于产生trace数据的数据源组件):
• Embedded Trace Macrocells (ETMs).
• AMBA Trace Macrocells.
• Program Flow Trace Macrocells (PTMs).
• System Trace Macrocells (STMs).
其中ETMs:嵌入式跟踪宏单元(ETM)体系结构定义了一个实时跟踪模块,提供对处理器的指令和数据跟踪。
(3)Trace links(trace信息传递过程中所需要的中间coresight组件):
• Trace funnels.
• Replicators.
• ATB bridges.
其中Trace funnel(漏斗):Trace funnel将来自所有源( sources)的跟踪合并到单个跟踪流中。
Replicators(分发器):与Trace funnel类型,单个输入数据源,多个输出数据源。
(4)Trace sinks(最终接收trace信息的coresight组件,每个跟踪接收器可以包括一个跟踪格式化程序):
• Trace Port Interface Units (TPIUs).将数据输出给外部调试器。
• Embedded Trace Buffers (ETBs).
• Trace Memory Controllers (TMCs).
TMCs主要分为ETR和ETF组件:
•TMCs-ETR:把数据存入到SDRAM中
•TMCs-ETF:可以把数据存入到SRAM中,还可以作为链路驱动,把数据输出给下一个输入设备

(5)Debug Ports and Access Ports:
以我手中的高通开发板(dragonboard410c)为例:
root@linaro-alip:~# ls -l /sys/bus/coresight/devices/
cti_cpu0/ cti_cpu3/ etm0/ etm3/ replicator0/ tpiu0/
cti_cpu1/ cti_sys0/ etm1/ funnel0/ tmc_etf0/
cti_cpu2/ cti_sys1/ etm2/ funnel1/ tmc_etr0/
有关详细信息,请参阅Documentation/devictree/bindings/arm/arm,coresight-*.yaml。
比如 Documentation/devicetree/bindings/arm/arm,coresight-etm.yaml:
description: |
CoreSight components are compliant with the ARM CoreSight architecture
specification and can be connected in various topologies to suit a particular
SoCs tracing needs. These trace components can generally be classified as
sinks, links and sources. Trace data produced by one or more sources flows
through the intermediate links connecting the source to the currently selected
sink.
The Embedded Trace Macrocell (ETM) is a real-time trace module providing
instruction and data tracing of a processor.
select:
properties:
compatible:
contains:
enum:
- arm,coresight-etm3x
- arm,coresight-etm4x
- arm,coresight-etm4x-sysreg
required:
- compatible
allOf:
- if:
not:
properties:
compatible:
contains:
const: arm,coresight-etm4x-sysreg
then:
$ref: /schemas/arm/primecell.yaml#
required:
- reg
properties:
compatible:
oneOf:
- description:
Embedded Trace Macrocell with memory mapped access.
items:
- enum:
- arm,coresight-etm3x
- arm,coresight-etm4x
- const: arm,primecell
- description:
Embedded Trace Macrocell (version 4.x), with system register access only
const: arm,coresight-etm4x-sysreg
reg:
maxItems: 1
clocks:
minItems: 1
maxItems: 2
clock-names:
minItems: 1
items:
- const: apb_pclk
- const: atclk
power-domains:
maxItems: 1
arm,coresight-loses-context-with-cpu:
type: boolean
description:
Indicates that the hardware will lose register context on CPU power down
(e.g. CPUIdle). An example of where this may be needed are systems which
contain a coresight component and CPU in the same power domain. When the
CPU powers down the coresight component also powers down and loses its
context.
arm,cp14:
type: boolean
description:
Must be present if the system accesses ETM/PTM management registers via
co-processor 14.
qcom,skip-power-up:
type: boolean
description:
Indicates that an implementation can skip powering up the trace unit.
TRCPDCR.PU does not have to be set on Qualcomm Technologies Inc. systems
since ETMs are in the same power domain as their CPU cores. This property
is required to identify such systems with hardware errata where the CPU
watchdog counter is stopped when TRCPDCR.PU is set.
cpu:
description:
phandle to the cpu this ETM is bound to.
$ref: /schemas/types.yaml#/definitions/phandle
out-ports:
$ref: /schemas/graph.yaml#/properties/ports
additionalProperties: false
properties:
port:
description: Output connection from the ETM to CoreSight Trace bus.
$ref: /schemas/graph.yaml#/properties/port
required:
- compatible
- clocks
- clock-names
- cpu
- out-ports
unevaluatedProperties: false
examples:
- |
ptm@2201c000 {
compatible = "arm,coresight-etm3x", "arm,primecell";
reg = <0x2201c000 0x1000>;
cpu = <&cpu0>;
clocks = <&oscclk6a>;
clock-names = "apb_pclk";
out-ports {
port {
ptm0_out_port: endpoint {
remote-endpoint = <&funnel_in_port0>;
};
};
};
};
ptm@2201d000 {
compatible = "arm,coresight-etm3x", "arm,primecell";
reg = <0x2201d000 0x1000>;
cpu = <&cpu1>;
clocks = <&oscclk6a>;
clock-names = "apb_pclk";
out-ports {
port {
ptm1_out_port: endpoint {
remote-endpoint = <&funnel_in_port1>;
};
};
};
};
...
或者参考:https://blog.csdn.net/weixin_45030965/article/details/128904115
coresight框架提供了在平台上表示、配置和管理coresight设备的中心点。只要使用正确的API,任何符合coresight的设备都可以在框架中注册:
(1)coresight_register
struct coresight_device *coresight_register(struct coresight_desc *desc);
/**
* struct coresight_desc - description of a component required from drivers
* @type: as defined by @coresight_dev_type.
* @subtype: as defined by @coresight_dev_subtype.
* @ops: generic operations for this component, as defined
* by @coresight_ops.
* @pdata: platform data collected from DT.
* @dev: The device entity associated to this component.
* @groups: operations specific to this component. These will end up
* in the component's sysfs sub-directory.
* @name: name for the coresight device, also shown under sysfs.
* @access: Describe access to the device
*/
struct coresight_desc {
enum coresight_dev_type type;
union coresight_dev_subtype subtype;
const struct coresight_ops *ops;
struct coresight_platform_data *pdata;
struct device *dev;
const struct attribute_group **groups;
const char *name;
struct csdev_access access;
};
注册函数采用 struct coresight_desc *desc ,并将设备注册到核心框架。
(2)coresight_unregister
void coresight_unregister(struct coresight_device *csdev);
/**
* struct coresight_device - representation of a device as used by the framework
* @pdata: Platform data with device connections associated to this device.
* @type: as defined by @coresight_dev_type.
* @subtype: as defined by @coresight_dev_subtype.
* @ops: generic operations for this component, as defined
* by @coresight_ops.
* @access: Device i/o access abstraction for this device.
* @dev: The device entity associated to this component.
* @refcnt: keep track of what is in use.
* @orphan: true if the component has connections that haven't been linked.
* @enable: 'true' if component is currently part of an active path.
* @activated: 'true' only if a _sink_ has been activated. A sink can be
* activated but not yet enabled. Enabling for a _sink_
* happens when a source has been selected and a path is enabled
* from source to that sink.
* @ea: Device attribute for sink representation under PMU directory.
* @def_sink: cached reference to default sink found for this device.
* @ect_dev: Associated cross trigger device. Not part of the trace data
* path or connections.
* @nr_links: number of sysfs links created to other components from this
* device. These will appear in the "connections" group.
* @has_conns_grp: Have added a "connections" group for sysfs links.
* @feature_csdev_list: List of complex feature programming added to the device.
* @config_csdev_list: List of system configurations added to the device.
* @cscfg_csdev_lock: Protect the lists of configurations and features.
* @active_cscfg_ctxt: Context information for current active system configuration.
*/
struct coresight_device {
struct coresight_platform_data *pdata;
enum coresight_dev_type type;
union coresight_dev_subtype subtype;
const struct coresight_ops *ops;
struct csdev_access access;
struct device dev;
atomic_t *refcnt;
bool orphan;
bool enable; /* true only if configured as part of a path */
/* sink specific fields */
bool activated; /* true only if a sink is part of a path */
struct dev_ext_attribute *ea;
struct coresight_device *def_sink;
/* cross trigger handling */
struct coresight_device *ect_dev;
/* sysfs links between components */
int nr_links;
bool has_conns_grp;
bool ect_enabled; /* true only if associated ect device is enabled */
/* system configuration and feature lists */
struct list_head feature_csdev_list;
struct list_head config_csdev_list;
spinlock_t cscfg_csdev_lock;
void *active_cscfg_ctxt;
};
unregister函数引用在注册时获得的 struct coresight_device *csdev 。
如果注册过程中一切顺利,新设备将显示在/sys/bus/coresight/devices下,如TC2平台所示:
root:~# ls /sys/bus/coresight/devices/
replicator 20030000.tpiu 2201c000.ptm 2203c000.etm 2203e000.etm
20010000.etb 20040000.funnel 2201d000.ptm 2203d000.etm
函数采用结构coresight_device,如下所示:
/**
* struct coresight_desc - description of a component required from drivers
* @type: as defined by @coresight_dev_type.
* @subtype: as defined by @coresight_dev_subtype.
* @ops: generic operations for this component, as defined
* by @coresight_ops.
* @pdata: platform data collected from DT.
* @dev: The device entity associated to this component.
* @groups: operations specific to this component. These will end up
* in the component's sysfs sub-directory.
* @name: name for the coresight device, also shown under sysfs.
* @access: Describe access to the device
*/
struct coresight_desc {
enum coresight_dev_type type;
union coresight_dev_subtype subtype;
const struct coresight_ops *ops;
struct coresight_platform_data *pdata;
struct device *dev;
const struct attribute_group **groups;
const char *name;
struct csdev_access access;
};
“coresight_dev_type”标识设备是什么,即 source link or sink ,而“coresight _dev_subtype”将进一步描述该类型。
enum coresight_dev_type {
CORESIGHT_DEV_TYPE_NONE,
CORESIGHT_DEV_TYPE_SINK,
CORESIGHT_DEV_TYPE_LINK,
CORESIGHT_DEV_TYPE_LINKSINK,
CORESIGHT_DEV_TYPE_SOURCE,
CORESIGHT_DEV_TYPE_HELPER,
CORESIGHT_DEV_TYPE_ECT,
};
/**
* union coresight_dev_subtype - further characterisation of a type
* @sink_subtype: type of sink this component is, as defined
* by @coresight_dev_subtype_sink.
* @link_subtype: type of link this component is, as defined
* by @coresight_dev_subtype_link.
* @source_subtype: type of source this component is, as defined
* by @coresight_dev_subtype_source.
* @helper_subtype: type of helper this component is, as defined
* by @coresight_dev_subtype_helper.
* @ect_subtype: type of cross trigger this component is, as
* defined by @coresight_dev_subtype_ect
*/
union coresight_dev_subtype {
/* We have some devices which acts as LINK and SINK */
struct {
enum coresight_dev_subtype_sink sink_subtype;
enum coresight_dev_subtype_link link_subtype;
};
enum coresight_dev_subtype_source source_subtype;
enum coresight_dev_subtype_helper helper_subtype;
enum coresight_dev_subtype_ect ect_subtype;
};
struct coresight_ops 是必需的,它将告诉框架如何执行与组件相关的基本操作,每个组件都有不同的需求集。对于该结构coresight_ops_sink,已经提供了结构coresight _ops_link和结构coresigght _ops_source。
struct coresight_ops {
const struct coresight_ops_sink *sink_ops;
const struct coresight_ops_link *link_ops;
const struct coresight_ops_source *source_ops;
const struct coresight_ops_helper *helper_ops;
const struct coresight_ops_ect *ect_ops;
};
下一个字段struct coresight_platform_dataupdate通过调用_get_coresight_platform_data()获取,作为驱动程序的_probe例程的一部分,struct devicedev获取嵌入在amba_device中的设备引用:
static int etm_probe(struct amba_device *adev, const struct amba_id *id)
{
...
...
drvdata->dev = &adev->dev;
...
}
特定类别的设备(源、链接或接收器)具有可以对其执行的通用操作(请参阅结构coresight_ops)。**组是仅与特定于该组件的操作相关的sysfs条目列表。“Implementation defined”定制预计将使用这些条目进行访问和控制。
出现在“coresight”总线上的设备的名称与其父设备相同,即出现在AMBA总线或平台总线上的真实设备。因此,这些名称基于Linux开放固件层命名约定,该约定遵循设备的基本物理地址和设备类型。例如:
root:~# ls /sys/bus/coresight/devices/
20010000.etf 20040000.funnel 20100000.stm 22040000.etm
22140000.etm 230c0000.funnel 23240000.etm 20030000.tpiu
20070000.etr 20120000.replicator 220c0000.funnel
23040000.etm 23140000.etm 23340000.etm
然而,随着ACPI支持的引入,真实设备的名称有点晦涩难懂。因此,引入了一种新的命名方案,以根据设备的类型使用更多通用名称。以下规则适用:
1) 绑定到CPU的设备根据CPU逻辑号命名。
比如:绑定到CPU0的ETM被命名为“etm0”
2) 所有其他设备都遵循“<device_type_prefix>N”模式,其中:
<device_type_prefix>:特定于设备类型的前缀。
N:根据探测顺序分配的序列号。
比如:tmc_etf0, tmc_etr0, funnel0, funnel1
因此,在新的方案中,设备可以显示为:
root:~# ls /sys/bus/coresight/devices/
etm0 etm1 etm2 etm3 etm4 etm5 funnel0
funnel1 funnel2 replicator0 stm0 tmc_etf0 tmc_etr0 tpiu0
下面的一些示例可能会引用旧的命名方案,而另一些可能引用较新的命名方案,以确认您在系统上看到的内容并不意外。用户必须使用出现在系统指定位置下的“名称”。
我手中的高通开发板 DragonBoard 410c 如下所示:
root@linaro-alip:~# ls /sys/bus/coresight/devices/
cti_cpu0 cti_cpu2 cti_sys0 etm0 etm2 funnel0 replicator0 tmc_etf0 tpiu0
cti_cpu1 cti_cpu3 cti_sys1 etm1 etm3 funnel1 stm0 tmc_etr0
接下来我就一我手中的开发版 DragonBoard 410c 为例子来调试。
每个CoreSight组件都有一个连接目录,其中包含指向其他CoreSight组件的链接。这允许用户探索跟踪拓扑,并对于较大的系统,确定给定源的最合适接收器。连接信息还可用于确定哪些CTI设备连接到给定组件。该目录包含一个nr_Links属性,该属性详细说明了目录中的链接数量。
对于ETM源,对于高通平台上的etm0,典型的安排是:
root@linaro-alip:~# ls -l /sys/bus/coresight/devices/etm0/connections/
total 0
lrwxrwxrwx 1 root root 0 Nov 19 21:51 cti_cpu0 -> ../../../858000.cti/cti_cpu0
-r--r--r-- 1 root root 4096 Nov 19 21:51 nr_links
lrwxrwxrwx 1 root root 0 Nov 19 21:51 out:0 -> ../../../841000.funnel/funnel1
从出口到 funnel1 :
root@linaro-alip:~# ls -l /sys/bus/coresight/devices/funnel1/connections/
total 0
lrwxrwxrwx 1 root root 0 Jan 1 02:46 in:0 -> ../../../85c000.etm/etm0
lrwxrwxrwx 1 root root 0 Jan 1 02:46 in:1 -> ../../../85d000.etm/etm1
lrwxrwxrwx 1 root root 0 Jan 1 02:46 in:2 -> ../../../85e000.etm/etm2
lrwxrwxrwx 1 root root 0 Jan 1 02:46 in:3 -> ../../../85f000.etm/etm3
-r--r--r-- 1 root root 4096 Jan 1 02:46 nr_links
lrwxrwxrwx 1 root root 0 Jan 1 02:46 out:0 -> ../../../821000.funnel/funnel0
然后从出口再到 funnel0:
root@linaro-alip:~# ls -l /sys/bus/coresight/devices/funnel0/connections/
total 0
lrwxrwxrwx 1 root root 0 Jan 1 02:53 in:4 -> ../../../841000.funnel/funnel1
-r--r--r-- 1 root root 4096 Jan 1 02:53 nr_links
lrwxrwxrwx 1 root root 0 Jan 1 02:53 out:0 -> ../../../825000.etf/tmc_etf0
查找第一个接收器(sink)tmc_etf0,这可以用来作为接收器收集数据,或用作沿着链进一步传播的链接:
root@linaro-alip:~# ls -l /sys/bus/coresight/devices/tmc_etf0/connections/
total 0
lrwxrwxrwx 1 root root 0 Jan 1 03:06 in:0 -> ../../../821000.funnel/funnel0
-r--r--r-- 1 root root 4096 Jan 1 03:06 nr_links
lrwxrwxrwx 1 root root 0 Jan 1 03:06 out:0 -> ../../../824000.replicator/replicator0
replicator0:
root@linaro-alip:~# ls -l /sys/bus/coresight/devices/replicator0/connections/
total 0
lrwxrwxrwx 1 root root 0 Jan 1 03:09 in:0 -> ../../../825000.etf/tmc_etf0
-r--r--r-- 1 root root 4096 Jan 1 03:09 nr_links
lrwxrwxrwx 1 root root 0 Jan 1 03:09 out:0 -> ../../../826000.etr/tmc_etr0
lrwxrwxrwx 1 root root 0 Jan 1 03:09 out:1 -> ../../../820000.tpiu/tpiu0
到达链中的最后一个接收器,tpiu0:
root@linaro-alip:~# ls -l /sys/bus/coresight/devices/tpiu0/connections/
total 0
lrwxrwxrwx 1 root root 0 Jan 1 03:10 in:0 -> ../../../824000.replicator/replicator0
-r--r--r-- 1 root root 4096 Jan 1 03:10 nr_links
etm0
-->cti_cpu0
-->funnel1
-->funnel0
-->tmc_etf0
-->replicator0
-->tpiu0
如下所述,当使用sysf时,启用接收器和源就足以成功跟踪。框架将根据需要正确启用所有中间链接。
使用CoreSight框架有两种方式:
(1)使用perf cmd行工具。
(2)使用sysFS接口直接与CoreSight设备交互。
首选前者,因为使用sysFS接口需要深入了解Coresight HW。以下各节提供了使用这两种方法的详细信息。
暂时省略
CoreSight跟踪器使用Perf框架的性能监视单元(PMU)抽象来表示。因此,Perf框架负责根据感兴趣的进程被调度的时间来控制何时启用跟踪。在系统中配置时,通过perf命令行工具查询时将列出CoreSight PMU:
root@linaro-alip:~/perf_test# ./perf list pmu
List of pre-defined events (to be used in -e):
cs_etm// [Kernel PMU event]
ARM64处理器其他的PMU事件:
root@linaro-alip:~# cat /sys/bus/event_source/devices/
armv8_cortex_a53/ breakpoint/ cs_etm/ software/
cs_etm PMU事件:
root@linaro-alip:~# cat /sys/bus/event_source/devices/cs_etm/
cpu0/ perf_event_mux_interval_ms
cpu1/ power/
cpu2/ sinks/
cpu3/ subsystem/
events/ type
format/ uevent
nr_addr_filters
root@linaro-alip:~# ls -l /sys/devices/cs_etm/
cpu0/ perf_event_mux_interval_ms
cpu1/ power/
cpu2/ sinks/
cpu3/ subsystem/
events/ type
format/ uevent
nr_addr_filters
无论系统中有多少可用跟踪器(通常等于处理器核心数量),“cs_etm”PMU都将只列出一次。CoreSight PMU的工作方式与任何其他PMU相同,即PMU的名称与配置选项一起列在正斜杠‘/’内。由于CoreSight系统通常具有多个接收器,因此需要将要使用的接收器的名称指定为事件选项。在较新的内核上,可用接收器列在($SYSFS)/bus/event_source/devices/cs_etm/sinks/:下的sysFS中:
root@linaro-alip:/sys/bus/event_source/devices/cs_etm/sinks# ls
tmc_etf0 tmc_etr0 tpiu0
正斜杠‘/’中的语法很重要。‘@’字符告诉解析器(the parser)即将指定接收器(sink ),并且这是用于跟踪会话的接收器。
perf可用于记录和分析程序的跟踪。
可以使用带有cs_etm事件的‘perf record’记录执行,指定要记录到的接收器的名称,例如:
perf record -e cs_etm/@tmc_etr0/u --per-thread
perf-record - Run a command and record its profile into perf.data
该命令将其中的性能计数器配置文件收集到Perform.data中,并且该命令不显示任何内容。
-e, --event=
Select the PMU event.
--per-thread
Use per-thread mmaps. By default per-cpu mmaps are created. This option overrides that and uses per-thread mmaps.
“perf report”和“perf script”命令可用于分析执行、合成指令跟踪中的指令和分支事件。”perf-inject”可用于用合成事件替换跟踪数据。–itrace选项控制合成事件的类型和频率(请参阅perf文档)。
有关如何将CoreSight与Perf工具一起使用的上述和其他示例的更多信息,请参阅OpenCSD GitHub存储库的“HOWTO.md”文件。
https://static.lwn.net/kerneldoc/trace/coresight/coresight.html
https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/how-to-debug-coresight-basics-part-3
文章目录一、Introduction二、AcronymsandClassification2.1Acronyms2.2Classification三、DeviceTreeBindings四、Frameworkandimplementation五、DeviceNamingscheme六、TopologyRepresentation七、Howtousethetracermodules7.1UsingthesysFSinterface7.2Usingperfframework参考资料一、IntroductionCoresight是一个允许调试基于ARM的SoC技术。它包括JTAG和硬件辅助跟踪的解决