以前的处理器芯片只有一个CPU核,通过JTAG调试相对比较简单,但是随着SOC系统越来越复杂,在一个芯片中集成多个CPU核,甚至是不同架构的多个Cluster。开发工具需要更为灵活的配置和足够的扩展性来适配不同的SOC,DTSL(Debug and Trace Service Layer)应运而生,提供了灵活的,强大的调试和跟踪功能。
DTSL是DS5底层调试协议软件,实现的功能包括调试平台的创建和配置,目标板的访问和调试控制,以及trace数据的控制和获取等。DTSL是基于Jython的描述语言,非常容易理解和修改实现所需要的配置和功能。比如可以支持不同SoC中CoreSight可以非常灵活配置;在设计阶段 FPGA上进行仿真时,不一定能够实现所有模块的功能,可以通过配置DTSL脚本来灵活配置。SoC的设计开发者还可以增加私有的调试模块,也可以通过DTSL的修改来进行控制。
本文将对ARM CoreSignt原理,DS5常用工具创建调试平台,调试和跟踪需要的文件以及常见问题和解决方法进行介绍,后续的文章中会介绍更多DTSL的细节以及更多的功能进行阐述。
CoreSight提供了SoC调试和跟踪的方案,从芯片设计来看,包括可配置的模块单元和相关的配置工具。主要是两大系列,分别是用于Debug和Trace,具体的可以参考CoreSight的相关文档,这里主要从创建和配置调试工具角度进行简要介绍。
CoreSight的每个模块和Cortex的每个核都可以用仿真器通过配置寄存器来进行控制和管理,这些寄存器是内存映射的,可以通过标准的memory操作的方式进行读写操作。每个CoreSight和Cortex的模块都有一个4KB的连续空间,基地址是非常重要的信息进行调试和跟踪相关的访问操作。
每个Cortex,都有对应的CSSoC的模块,分别对应Cortex的不同核的调试部分,这部分的文档和资料请参考ARM的架构手册(ARM Architecture Manual)。
CoreSight中用于debug的主要模块包括:
CoreSight中用于Trace功能的模块主要包括:
ETM和PTM有同样的功能,产生压缩的指令执行信息,一般来说每个Cortex的核都有一个对应的ETM或者PTM。ETMv3(比如Cortex-A7)会获取CPU核的所有执行执行信息;PTM(Cortex-A15)和ETMv4只是获取执行执行路径,比如跳转指令,来提高trace的效率。
CSITM和CSSTM获取一些事件信息,ITM用于软件事件,比如其他模块可以操作ITM的寄存器来产生事件;STM用于捕获硬件事件。
CSHTM获取AHB的交换数据,很少使用,并且在DS5的5.18版本已经取消了对HTM的支持。
ETB提供一个片上缓存,一般比较小,只有4K-16KB,trace信息会被覆盖。
TPIU提供了trace的接口,可以用DSTream来进行外部Trace缓冲,DSTream提供过了4GB的缓冲空间。
TMC包括CSETR和CSETF,ETR类似于ETB,但是不是独享的buffer,可以把Trace信息存到系统中的其他内存空间,比如外部DDR空间;ETF是个FIFO,用于缓冲突发的Trace数据,一般是16KB。
Cortex的调试和CoreSight的模块在每个SoC中是不同的,DTSL的强大就是对所有基于ARM的SoC都可以进行通过几个工具生成配置文件,简单的修改来实现灵活的调试和Trace功能。
在DS5中,针对不同的SoC架构,需要一些配置,主要涉及到如下三个文件:
根据SoC系统的不同,会对应不同的配置RVC文件,主要包括每个debug和trace模块的信息,索引和基地址等,DTSL的脚本会解析rvc文件的内容,然后针对特定的SoC进行底层的访问和控制。
生成RVC文件以后,可以通过cdbimport或者DS5的图形界面生成调试描述文件,用于DS5的UI界面和底层的交互入口。
这个文件也是工具生成的,是DTSL的核心,基于Jythong。在生成的过程中,由于rvc只有每个CoreSight的模块的信息,但是没有模块之间怎么链接的信息,由于信息不足的原因,在生成py文件的时候会做出一些假设,根据SoC的拓扑架构不同,功能需求不同,需要手动查看或者修改来适配SoC的实际情况。
在DS5中,除了集成开发环境,编译器以外,还提供了几个有用的SoC创建和配置,以及底层访问和控制工具,主要用于芯片的bring up和底层调试。
DbgHWConfig提供了JTAG的自动扫描,通过读取SoC的ROMTable来获取SoC的Debug和Trace模块,并且生成rvc文件。DbgHWConfig也可以根据SoC的拓扑结构和配置信息,进行手动的配置,产生rvc文件。
生成rvc文件以后,可以通过命令行的cdbimport生成调试平台的配置文件和基本的dtsl_config_script.py模版,如前所述,在生成过程中有些假设条件,需要仔细查看假设的条件是否和SoC的实际情况是否匹配。
对每个新的SoC,首先需要了解SoC的内部Debug和Trace的拓扑架构,以及一些基本信息,比如每个模块的基地址,每个端口的配置情况,比如Funnel的那个端口链接到那个Trace源等信息。
如果已经有SoC,可以用DbgHWConfig的自动扫描功能,读取SoC的ROMTable来自动生成rvc文件。
启动DS5里面的DBGHWConfig:
连接DSTReam仿真器:
进行自动配置:
在SoC的设计阶段,由于没有硬件平台,也可以在DbgHWConfig工具里面手动配置生成rvc文件。
当手动配置时,需要特别注意CoreSight的模块的顺序,对应Device的Index,因为DTSL进行解析的时候,是根据index进行映射的。一般默认的情况是把Trace Sink放在低端ROMTable地址,也就是index值比较小。当然,也可以简单修改DTSL的映射逻辑进行适配。
在手动配置时,需要注意修改每个模块的基地址。
在命令行下直接执行:
在生成过程中会提示一些假设,需要查看是否和实际芯片一致,并做相应的修改。
把生成的配置文件导入到DS5的配置数据库:
在DS5的debugger中就可以看到最新导入的目标平台,可以进行简单测试。
由于DTSL解析RVC文件的时候,是根据RVC文件的每个模块的序列号进行映射的,如果DTSL默认解析的顺序和SoC的实际顺序不一致,对应DS5中的操作也将使用错误的内存映射寄存器进行操作,从而得不到想要的结果。
由于cdbimport不清楚SoC系统内部链接方式,会做出一些假设,比如使用的Funnel的端口号,如果有多个Funnel,Funnel的链接方式不能正确映射。
本文只是对ARM SoC的Debug和Trace做基本的介绍,包括涉及的主要文件,所用的工具,以及新的SoC平台如何创建配置文件,具体DTSL中如何进行映射和操作,在后续的文章中做进一步讨论。
DS5的最新版本5.19中(2014年7月中发布),对如何常见平台做了很大程度的改进和优化,创建新的平台更为容易和快捷,并避免常发生的配置错误问题。