文章目录
- 一、Introduction
- 二、Acronyms and Classification
- 2.1 Acronyms
- 2.2 Classification
- 三、Device Tree Bindings
- 四、Framework and implementation
- 五、Device Naming scheme
- 六、Topology Representation
- 七、How to use the tracer modules
- 7.1 Using the sysFS interface
- 7.2 Using perf framework
- 参考资料
一、Introduction
Coresight是一个允许调试基于ARM的SoC技术。它包括JTAG和硬件辅助跟踪的解决方案,为实时调试和收集跟踪信息提供了系统范围的解决方案。
硬件辅助跟踪在处理具有许多SoC和其他组件(如GPU和DMA引擎)的系统时变得越来越有用。ARM通过不同的组件开发了硬件辅助跟踪解决方案,每个组件在合成时添加到设计中,以满足特定的跟踪需求。组件通常分为 source、link 和 sinks,通常使用AMBA总线进行查找。
Sources 根据用户配置的跟踪场景生成表示处理器指令路径的压缩 stream 。stream 流经CoreSight系统(通过ATB总线)使用 links 将 the emanating source 连接到 a sink(s)。Sinks充当CoreSight实施的端点,要么将压缩流存储在内存缓冲区中,要么创建到外部世界的接口,在那里数据可以传输到主机,而不必担心填满板载CoreSight内存缓冲区。
典型的CoreSight系统如下所示:
*****************************************************************
**************************** AMBA AXI ****************************===||
***************************************************************** ||
^ ^ | ||
| | * **
0000000 ::::: 0000000 ::::: ::::: @@@@@@@ ||||||||||||
0 CPU 0<-->: C : 0 CPU 0<-->: C : : C : @ STM @ || System ||
|->0000000 : T : |->0000000 : T : : T :<--->@@@@@ || Memory ||
| #######<-->: I : | #######<-->: I : : I : @@@<-| ||||||||||||
| # ETM # ::::: | # PTM # ::::: ::::: @ |
| ##### ^ ^ | ##### ^ ! ^ ! . | |||||||||
| |->### | ! | |->### | ! | ! . | || DAP ||
| | # | ! | | # | ! | ! . | |||||||||
| | . | ! | | . | ! | ! . | | |
| | . | ! | | . | ! | ! . | | *
| | . | ! | | . | ! | ! . | | SWD/
| | . | ! | | . | ! | ! . | | JTAG
*****************************************************************<-|
*************************** AMBA Debug APB ************************
*****************************************************************
| . ! . ! ! . |
| . * . * * . |
*****************************************************************
******************** Cross Trigger Matrix (CTM) *******************
*****************************************************************
| . ^ . . |
| * ! * * |
*****************************************************************
****************** AMBA Advanced Trace Bus (ATB) ******************
*****************************************************************
| ! =============== |
| * ===== F =====<---------|
| ::::::::: ==== U ====
|-->:: CTI ::<!! === N ===
| ::::::::: ! == N ==
| ^ * == E ==
| ! &&&&&&&&& IIIIIII == L ==
|------>&& ETB &&<......II I =======
| ! &&&&&&&&& II I .
| ! I I .
| ! I REP I<..........
| ! I I
| !!>&&&&&&&&& II I *Source: ARM ltd.
|------>& TPIU &<......II I DAP = Debug Access Port
&&&&&&&&& IIIIIII ETM = Embedded Trace Macrocell
; PTM = Program Trace Macrocell
; CTI = Cross Trigger Interface
* ETB = Embedded Trace Buffer
To trace port TPIU= Trace Port Interface Unit
SWD = Serial Wire Debug
虽然组件的目标配置是通过APB总线完成的,但所有跟踪数据都在ATB总线上带外执行。CTM提供了一种在CoreSight组件之间聚合和分发信号的方法。
CoreSight框架提供了一个中心点来表示、配置和管理平台上的CoreSight设备。第一个实施以基本跟踪功能为中心,启用ETM/PTM、funnel、replicator、TMC、TPIU和ETB等组件。未来的工作将使更复杂的IP块,如STM和CTI。
每个逻辑处理器上都与一个ETM,CTI绑定。
二、Acronyms and Classification
2.1 Acronyms
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
2.2 Classification
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).
(3)Trace links(trace信息传递过程中所需要的中间coresight组件):
• Trace funnels.
• Replicators.
• ATB bridges.
(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/
三、Device Tree Bindings
有关详细信息,请参阅Documentation/devictree/bindings/arm/arm,coresight-*.yaml。
在编写ITM驱动程序时,未提供STM和CTI,但预计将随着解决方案的成熟而添加这些驱动程序。
四、Framework and implementation
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”定制预计将使用这些条目进行访问和控制。
五、Device Naming scheme
出现在“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 为例子来调试。
六、Topology Representation
每个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时,启用接收器和源就足以成功跟踪。框架将根据需要正确启用所有中间链接。
七、How to use the tracer modules
使用CoreSight框架有两种方式:
(1)使用perf cmd行工具。
(2)使用sysFS接口直接与CoreSight设备交互。
首选前者,因为使用sysFS接口需要深入了解Coresight HW。以下各节提供了使用这两种方法的详细信息。
7.1 Using the sysFS interface
暂时省略
7.2 Using perf framework
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]
无论系统中有多少可用跟踪器(通常等于处理器核心数量),“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