ARM调试接口——概述
引言
在本文中,主要介绍(翻译)ARM调试接口(Arm Debug Interface, ADI)的总体内容.
水平有限,难免存在出错的地方.具体还请查阅手册.
本文一共包含以下几个部分:
- ADI版本
- ADI的用途
- 调试链路
- ADI v6的实现细分
- 调试端口(Debug Port, DP)
- 访问端口(Access Ports, APs)
- 设计决策和实现范例
- 电源要求
ADI版本
ADIv6是第六代ARM调试接口的主要版本
注意: ADIv6术语指代了6.0版本与其修订版本.到目前为止,ADIv6和ADIv6.0指的是同一个版本.
所有的早期ADI版本均基于IEEE 1149.1 JTAG接口, 但其仅用于访问ARM处理器核心和嵌入式跟踪微单元(ETM).下面列出这些版本:
- Debug interface version 1 and 2
在ARM7TDMI® 和 ARM9® 系列上实现. - Debug interface version 3
针对ARM10™处理器系列推出. - ADIv4
首个与ARM架构关联而不依赖于处理器内核具体实现的版本.ARM官方建议将ADIv4与ARMv6架构的实现一起使用. - ADIv5
移除了ADI与处理器内核之间的联系,并对调试端口(DPs)进行正式的版本编号.
ADIv6.0提供了一种分层系统,该系统允许通过内存映射(memory-mapped)的方式从多个不同的代理访问系统的所有部分(包括片外调试器和片上软件).
对于非内存映射的系统资源的访问通过内存映射的抽象层进行.例如,为了控制JTAG设备,需要提供一个能够进行JTAG控制的内存映射组件.
ADIv6包含下面这些层级:
- 物理层(JTAG或SWD): 有关JTAG物理层信息可以查阅IEEE的JTAG标准:
IEEE Standard Test Access Port and Boundary Scan Architecture
. - 协议层(JTAG或SWD): 用于管理JTAG和SWD的状态机.
- 数据链路层 (JTAG或SWD): 用于访问调试端口(DP)寄存器和访问端口(AP)寄存器.
- 访问端口(AP)层: 用于访问SoC中的一个或多个子系统.
为了新版本的增强功能,ADIv6.0对DP和AP作出了修改:
- 新版DP架构版本为
DPv3
.ADIv6仅支持使用DPv3.
注意: DPv3与早期版本不完全向后兼容.
- 新版AP架构为
APv2
.ADIv6仅支持使用APv2.
注意: ADIv5 AP称为APv1
ADI的用途
ADI提供了对嵌入式片上系统(SoC)上调试组件所提供的各种调试功能的访问支持.
本节总结了您可以在SoC中找到的各种调试功能.其包含以下内容:
- 嵌入式核心调试功能
- 系统调试功能
- CoreSight和ARM调试接口之间的兼容性
嵌入式核心调试功能
嵌入式微处理器可以提供以下调试功能,以启用对应用程序的调试:
- 处理器状态修改
允许外部主机修改处理器状态,通过内部寄存器和内存系统决定内容. - 处理器状态评估
允许外部主机访问内部寄存器和内存系统的内容,以评估处理器的运行状态. - 可编程调试事件
允许外部主机对调试事件进行编程.外部主机通过配置调试逻辑,在发生特殊事件(例如,程序流到达代码中的特定指令)时,内核进入一种特殊的执行模式,在该模式下,内核状态可以在外部进行查看或修改.在本章中,这种特殊的执行模式被称之为调试状态. - 进入或退出调试状态
允许外部主机决定处理器何时应进入或退出调试状态,或者强制处理器进入或退出调试状态. - 跟踪特性
跟踪与可编程事件相关联的程序流.
提供这些功能的技术示例如下:
- Armv8调试架构.具体请参阅
Arm® Architecture Reference Manual, Armv8
. - 嵌入式跟踪微单元(ETM).具体请参阅
ETM Architecture Specification
.
ADIv6实现也可以访问实现IEEE 1149.1 JTAG接口的旧式组件,该接口可以访问实现ADI早期版本的处理器中的调试资源.
系统调试功能
调试信息超出了嵌入式微处理器的范畴(作者注:这被称为系统调试),其包含以下内容:
- SoC内嵌的内核以外的组件.
- 系统的互连结构.
为了实现对上述内容的调试,SoC提供了以下系统调试机制:
- 外部主机访问
允许外部主机访问以下的调试信息:
- 嵌入式微处理器内核中可能看不见的系统状态参数.
- 跟踪有关互连结构的信息,例如访问微处理器核心或者访问其他设备(DMA引擎等).
- 访问诊断信息
一种高效收集并使用流式传输诊断信息(例如程序跟踪)的机制. - 诊断信息发送(Diagnostic messaging)
一种软件和调试器之间的低入侵(low-intrusion)诊断消息传递机制. - 交叉触发(Cross-triggering)
该机制允许调试组件间互相发送信号.
CoreSight和ARM调试接口之间的兼容性
ADIv6与Arm CoreSight架构相兼容,即:
- ADIv6可以访问和控制与Arm CoreSight相兼容的组件.
- ADIv6规范不需要任何调试组件即可符合CoreSight架构.
调试链路
该规范的一个基本法则是:调试链路提供一种面向AP层执行内存映射事务的方法.这里所述的调试链路包括:
- JTAG/SWD, 使用ADIv6 DP.
- 典型的功能层级,例如PcIe, USB和IP Sockets.
- 片上软件.
由于应用了此法则,对于使用AP层的调试代理而言,只需要了解如何使用内存映射的事务就足够了.
为了确定系统的身份和拓扑结构,调试代理需要使用一个起始地址来询问系统.单个地址(最多可达64位)提供待识别的组件列表中的第一个组件的基址.第一个组件可能是以下中的一个:
- 除了ROM表以外的单一Coresight组件,并且必须是唯一可以通过该连接进行访问的组件.
- 一个访问端口(Access Port,AP).一个AP提供了连接到另一个系统的桥梁.一个内存访问端口(MEM-AP)提供了一个进入内存系统的窗口,同时提供了待识别组件列表的第一个组件的基址,该基址需用于进一步识别其他组件的地址.
允许从其他MEM-APs访问MEM-APs.但是ARM强烈建议不要以这种方式实现MEM-APs的嵌套.
- 一个ROM表.该ROM表中包含待识别的一个或多个组件的地址.
ROM表允许指向另一个ROM表,且没有嵌套深度限制.
这里给出一张图作为这三种内存系统的例子:(作者注:也可以认为是寻址模式)
片上调试软件不需要在每次操作中都从最顶层开始访问,其可以在较低层进行访问操作.如图A1-1所示,要使内存系统2中的CPU中的自托管调试软件访问内存系统2中的组件,它只能使用主机处理器的内存系统中的组件.这不需要通过位于内存系统2中的MEM-AP进行,其可以直接访问MEM-AP的下一层.
如图A1-1中Coresight组件1所示,CoreSight组件可能位于所有内存系统之外的顶层,例如,跟踪端口接口单元(TPIU)组件在所有内存系统之间共享,并且只能由外部调试器进行访问.
ADI v6的实现细分
ADI的实现为调试器提供了一个标准接口,用于访问系统中的调试资源,这些资源使用特定的方法来暴露其调试信息.
ADI的实现有时候也被称作Debug Access Port (DAP).
ADI连接
图A1-2中的逻辑框图显示了如何在调试器和要调试的系统之间连接的ADI实现:
为了访问一个调试资源,调试器需要向ADI传递合适的资源地址——由此选择恰当的资源以执行请求,然后访问待调试系统提出的特定资源传输方法.ADI的实现包括以下内容:
Access Port(AP)
AP使用特定资源的传输机制来访问待调试系统中的调试信息,并使用本文所述的AP访问机制将信息传递给DP.调试资源的例子有:
- 处理器核心中的调试寄存器
- ETM或者跟踪端口调试(trace port debug)寄存器
- 内存系统
- 一个传统的JTAG设备
调试器采用AP访问来交换AP寄存器中的保存的信息,我们将在访问端口
一节详细讨论此过程.
再次强调: 这里的标准是基于APv2的.ADIv6仅支持使用APv2.
Debug Port(DP)
DP为调试器提供了通用接口,以访问AP中保存的信息. DP包含以下内容:
- 关于调试器的物理连接, ADIv6支持
JTAG
,SWD(Serial Wire)
,SWJ(Serial Wire JTAG)
- DP寄存器存储了实现DP传输机制所需的信息.调试器使用
DPACC
扫描链在DP寄存器间交换信息.(我们将在对AP和DP寄存器进行访问
一节进行讨论)
更多的关于DP寄存器的信息请参阅
DP register descriptions on page B2-53
再次强调: 这里的标准是基于DPv3的.ADIv6仅支持使用DPv3.
资源特定(Resource-specific)的传输
DP和APs之间的连接将执行以下的任务:
- 根据调试器提供的地址信息,选择相应的调试资源
- 在AP与DP之间传输数据
对AP和DP寄存器进行访问
图A1-2中显示了调试器在逻辑上如何访问DP和AP寄存器:
- DP参与了对
APACC
请求的响应,但其参与过程在APACC层面上对调试器的而言是透明的. 调试器可以使用
DPACC
方法访问DP寄存器,并实现其中一项:- 设置即将到来的
APACC
参数.例如,通过设置DP的SELECT寄存器来选择所需的AP.(具体见手册B2-75) - 读取此前
APACC
操作的状态信息.例如,产生粘滞标志(sticky flag)的状态可以从DP中的CTRL/STAT
寄存器中读取.
- 设置即将到来的
虽然本规范用图A1-2所示的元素来定义ADIv6,但并不是必须以这种方式来构建实现.不过,图中所示的元素为描述编程模型(programmers’ model)提供了一种方便的表示,这也是本规范的目的.
调试端口(DP)
ADI的实现包含单个DP,该DP提供以下功能:
- 与接口的外部物理连接. 构成物理连接的信号取决于DP类型.
- 一种获取DP的识别码的方法.
- DP和AP访问方式,取决于DP的类型.
- 终止看似失败的寄存器访问的方法(可选).
- 确定ADI使用的地址大小的方法.
- 一个用于告知调试器从哪里开始搜索(包括ROM表和AP)组件的指针.
ADIv6支持下面这些调试端口:
1. JTAG调试端口(JTAG-DP)
JTAG-DP通过符合IEEE 1149.1标准的DBGTAP
扫描链来读取和写入寄存器信息.
这里的规范是基于JTAG-DP协议版本v1的.ADIv6仅支持JTAG-DP协议版本v1.
2. 串行线调试端口(SWD-DP)
SW-DP是一个双引脚串行接口,它使用基于数据包的协议来读取或写入寄存器.该协议要求主机(即调试器)和目标(即ADI)之间的通信过程如下:
- 首先,主机对目标的发起数据包请求,其中指示访问DP寄存器(DPACC)还是AP寄存器(APACC),并携带一个2位寄存器地址.
- 然后,目标对主机做出ACK响应.
- 最后为数据传输阶段(必要的话).可以从主机到目标传输数据,或者从目标到主机传输数据(取决于第一阶段).
3. SW/JTAG调试端口(SWJ-DP)
SWJ-DP接口结合了串行线调试(SWD)和JTAG数据链路协议,其使用以下机制:
- 携带信号的引脚在两种选项间共享.
- 调试器可以选择其中一个调试协议(JTAG或SWD)进行操作.
更多信息,参阅:
Chapter B3 The JTAG Debug Port (JTAG-DP).
Chapter B4 The Serial Wire Debug Port (SW-DP)
Chapter B5 The Serial Wire/JTAG Debug Port
(SWJ-DP).
IEEE Standard 1149.1 Test Access Port and Boundary Scan Architecture
包含有关JTAG扫描链要求的详细信息.
访问端口(APs)
AP使用特定于资源的传输机制来访问待调试的系统中的调试信息,然后将信息传递给DP.调试器可以使用标准协议通过标准物理连接获取该信息.
一个AP的实现取决于它所访问的资源.本规范包含两种从编程者角度出发的资源类型:
- 内存映射资源(Memory-mapped resouce).例如,对于调试外设,ADIv6为其定义了一个内存访问端口(MEM-AP)的编程模型.
- 旧版IEEE 1149.1 JTAG设备,ADIv6为其定义了JTAG访问端口,并与一个编程模型关联起来.
具体的编程模型我们将在后面部分提到.
注意: 以下内容适用于本文中提到的AP
- 本规范没有规定AP与资源之间传输的具体要求.特别地,它不要求MEM-AP使用总线与被调试的系统连接.例如,ADIv6可能直接集成到资源中.但是从逻辑上讲,MEM-AP总是访问被调试系统中的内存映射资源,这就是为什么本规范将MEM-AP对被调试系统的访问操作描述为内存访问.
- 未来可能有更多的ARM AP可用.
- ADI可以包含非ARM供应商指定的AP.
所有AP都必须遵循基本的标识规范,调试器必须能够识别并忽略其不支持的AP.ADIv6要求符合APv2的AP是0x9
类型的Coresight组件,且实现了CoreSight和APv2的编程模型. 具体见Chapter C1 About the AP.
正如ADI v6的实现细分
一节所述:
- 最简单的ADI仅包含一个AP(MEM-AP或JTAG-AP).
- ADI可以包含多个AP.例如所有的MEM-AP,所有的JTAG-AP,多个MEM-AP和JTAG-AP混合.
- 调试器必须能够识别和忽略其不支持的AP.
使用DP访问APs
图A1-3显示了与调试器的物理连接和被调试系统的调试资源之间的不同层次.层次设计为有效访问被调试系统提供了保证,此外几个层次在ADI的实现中提供了相应的寄存器.本节将介绍对这些寄存器的访问是如何实现的.
一个DP支持两种类型的访问,分别是DP访问和AP访问.由于调试器通常具有串行接口,因此进行这些访问的方法应尽可能短,并且所有访问均为32位.
此处给出的描述是从连接到JTAG调试端口的调试器对寄存器的扫描链访问.不过,SWD的访问过程也类似.我们将在SWD一章(Chapter B4 The Serial Wire Debug Port (SW-DP))讨论二者间的差异.
所有从调试器发起的AP、DP访问事务包含2个地址位,称为A[3:2]
:
- 对于DP寄存器的访问,
A[3:2]
的地址位与SELECT.DPBANKSEL
寄存器共同决定要访问哪个寄存器. - 对于AP寄存器的访问,
SELECT.ADDR
寄存器和SELECT1.ADDR
寄存器组合形成了64位AP地址空间中4个AP寄存器组的60位地址.地址位A[3:2]
则用于选择这4个寄存器组中的其中一个.
所有的AP和DP寄存器的地址位的最低两位[1:0]
为0b00
.
例如,要访问AP中位于地址0x00000000000000000000
的寄存器3(在Bank 1中),调试器需要这样做:
写入2个DP寄存器以选中AP的Bank 1分块:
- 向
SELECT1.ADDR
写入0x00000000
. - 向
SELECT.ADDR
写入0x0000001
.
- 向
- 为了读取选中的Bank分块中的寄存器3,使用地址
A[3:2] = 0b11
进行一次AP访问操作.
如上所述,一次AP访问操作需要SELECT1.ADDR
,SELECT.ADDR
,A[3:2]
的参与.调试器可以在不修改SELECT
系列寄存器的情况下,修改A[3:2]
的值以访问从0x10
到0x1C
的4个寄存器.
此处的访问模型在图A1-3中给出.此图展示了SELECT
和SELECT1
和APACC扫描链上的A[3:2]
相组合以形成AP寄存器的地址.
该图还包含了JTAG-DP的其他部分,这些部分将在以后的章节中讨论.此外,图C2-1和图C3-1将分别讨论MEM-AP和JTAG-AP实现,我们将在以后的章节中给出.
MEM-AP详细说明指南
为了理解和使用MEM-AP,您需要了解:
- MEM-AP本身.
- MEM-AP寄存器.
- 您通过MEM-AP所访问的标准调试组件寄存器.
具体请见:
Chapter C1 About the AP.
Chapter C2 The Memory Access Port (MEM-AP).
MEM-AP可供0个、1个或多个调试组件访问.任何符合ARM通用识别寄存器规范(ARM Generic Identification Registers specification)的调试组件都会实现一组组件识别寄存器.将在Chapter D1 Component and Peripheral ID Registers讨论这些寄存器.
注意: 如下面将要讨论的
设计决策和实现范例
一节所示,一个只有一个功能调试组件的系统也可以实现一个ROM表.
共享资源的MEM-AP可能会受到相互依赖的影响.双MEM-AP解决方案允许外部调试器和片上软件可靠地访问共享硬件的MEM-AP,具体见Twin MEM-APs一节.
JTAG-AP详细说明指南
为了理解和使用JTAG-AP,您需要了解:
- JTAG-AP本身.
- JTAG-AP寄存器.
具体请见(在以后的章节中讨论):
Chapter C1 About the AP.
Chapter C3 The JTAG Access Port (JTAG-AP).
JTAG-AP提供一个标准的JTAG连接到一个或多个传统组件.JTAG-AP与组件之间的连接由IEEE 1149.1-1990 IEEE Standard Test Access Port and Boundary Scan Architecture
定义.关于如何使用这种连接的细节不在本规范的范围内.
小结:使用AP对调试资源进行访问
通过访问AP的方式,可以获取如图A1-3中所示的调试资源.
总结如下:
- 在MEM-AP中,调试资源在逻辑上是由内存映射的.关于MEM-AP如何和调试资源间相连超出了本规范的讨论范围. 关于访问的方法,在MEM-AP register accesses and memory accesses on page C2-170 中给出
- 在JTAG-AP中,调试资源通过标准的JTAG串行连接连接,如
IEEE 1149.1-1990 IEEE Standard Test Access Port and Boundary Scan Architecture
所定义.有关如何访问资源,将在后续的章节中给出.
设计决策和实现范例
图A1-2所示的逻辑框图介绍了构成ADI的组件.
在实施ADI之前,您必须做出本节中描述的一些设计决策,涵盖了接口的以下功能块:
- DP的设计决策
- APs的设计决策
注意:本架构规范是为实现ARM调试接口的工程师和使用ARM调试接口的工程师编写的.如果您阅读本规范是为了了解更多关于某个特定ARM调试接口实现的信息,您必须了解在该实现中所做出的设计决策.这些选择可能隐含在与调试接口的连接中,但如果您不确定做出了哪些选择,您需要联系调试接口的实现者以获得更多信息.
DP的设计决策
DP决定ADI向调试器提供哪种类型的物理连接.ADI的每个实现都提供一个DP,为设计提供物理连接.您可以从以下DP类型中选择:
- JTAG-DP
- SW-DP
- SWJ-DP
注意:
- 在ADI的图示中,标记为DP的组件代表任何可用选项.
- ARM未来可能提供更多类型的DP.
APs的设计决策
一个简单的ADI使用单个AP连接单个调试组件,例如:
- 一个与单个微处理器核心连接的MEM-AP(如图A1-4所示).
- 一个与单个传统IEEE 1149.1设备相连接的JTAG-AP(如图A1-5所示).
一个只有一个调试组件的系统往往会实现一个ROM表,这就需要如图A1-6所示的实现方式.
由于一个ADI可以包括多个AP,所以AP的设计决策必须从两个层面进行:
- 选择ADI中AP的数量,以及每个AP的类型.
- 每个AP的实现决策,包括JTAG-AP和MEM-AP.
下面我们将讨论上面的两个层面的内容.
顶层AP规划决策
在一个比较复杂的系统中,可以有多个AP,每个AP可以连接到多个组件,或者多个地址空间.一个AP可以作为以下三种类型之一来实现:
- 作为一个内存访问端口(MEM-AP)与内存映射的调试总线连接.调试总线直接连接到一个或多个调试寄存器文件(debug register file).
- 作为一个MEM-AP与内存映射的系统总线连接.MEM-AP与系统总线的连接提供了对一个或多个调试寄存器文件的访问.
- 作为一个JTAG访问端口(JTAG-AP).一个JTAG-AP直接连接到一个或多个JTAG设备,并允许连接到传统硬件组件.
注意: 传统硬件组件和JTAG-AP之间的连接由JTAG标准定义. 请参见JTAG章节的有关内容.
如果您正在设计或选择ADI,您需要指定需要多少个、哪些种类的AP,这在很大程度上取决于您系统所连接的调试组件.
图A1-7展示了一个更为复杂的ADI,并解释了不同的AP类型.
ADIv6架构规范支持以下特性:
- 允许ADI实现包含多种类型的AP.
- 单个MEM-AP允许访问多个寄存器文件.
- 允许AP访问混合的系统内存和调试寄存器文件.
但是,在使用这些特性时,您必须遵守以下规则:
- 所有AP都必须遵循本规范所述的基本识别标准.
- 调试器必须采取一种方法来忽略其无法识别的AP.
正如图A1-3所示的那样,DP可以是ADIv6所定义的任何类型.
MEM-AP的决策
以下是MEM-AP必须做出的设计决策:
1. 根据调试组件的具体需求作出决策.
对于MEM-AP来说,需要做出的主要决策包括MEM-AP和内存映射调试组件之间的连接形式,包括:
- 是否有必要采取总线连接.
- 如果采取总线连接,那么需要采用的总线宽度是多少.
- MEM-AP使用的内存映射所占据的地址空间.
2. 包含ROM表
如果MEM-AP连接到多个调试组件,则系统必须包含一个或多个ROM表以提供有关调试系统的信息. 只有一个其他组件的系统不需要ROM表,但是系统设计者仍然可以将其包含在内.
更多的信息参阅ROM Tables on page C2-168
3. 采用由实现定义(IMPLEMENTATION DEFINED)的MEM-AP特性
- 如果连接宽度小于32位,必须采用某些功能.
- 调试组件可以对连接进行权限管理.例如,一个组件可能需要32位的访问权限.
更多额外的MEM-AP特性,请参阅:
MEM-AP functions on page C2-173
MEM-AP implementation requirements on page C2-188.
更多有关MEM-AP的实现细节,请见Chapter C2 The Memory Access Port (MEM-AP)
一节.
JTAG-APs的决策
以下是JTAG-APs必须做出的设计决策:
1. 连接到JTAG-AP的JTAG扫描链数量
一个JTAG-AP可以连接到最多8个JTAG扫描链.这些扫描链可以在被调试的系统中的多个设备或部件之间进行拆分.
2. 每个扫描链中的测试访问端口(TAP)数量
单个JTAG扫描链可以承载多个TAP.不过ARM官方建议一个扫描链仅承载一个TAP.
更多的内容我们将在JTAG章节中讨论.
电源要求
CDBGPWRUPREQ
和CSYSPWRUPREQ
是DP功能的一部分,不能以直接访问功能网络的形式进行操作.为此,引入电源粒度请求(Granular Power Requester,GPR)作为主要的电源请求功能.GPR功能可集成在独立组件中,也可以选择放置在ROM表中.
作者注:
CDBGPWRUPREQ
和CDBGPWRUPREQ
, 是系统和调试电源的控制字段, 是DP寄存器组CTRL/STAT
中的一部分.二者分别用于请求启动调试电源和请求启动系统电源.
独立的GPR编程模型已被废弃,现推荐将其放置于ROM表中.包含GPR的ROM表编程模型将在Power domain entries on page D4-321中讲解.
在不同电源域的组件将在ROM表中被识别与指向.基于此,调试器可以识别不同调试组件所属的电源域,并按需使用电源域.GPR最多支持32个调试电源域.
为了支持向系统的其他部分请求电源,GPR功能被扩展到支持多达32个电源域的电源请求.这些电源域没有在ROM表中定义,而是由实现定义的.这些电源域被称为系统电源域(system power domain).系统电源域可以包含需要被调试器访问到的组件,即便它们不具备ROM表所中描述的任何调试功能.系统互连配置组件是其中的一个例子.
为了确保通过功能网络连接的调试器能够成功进行调试,第一个GPR必须在系统的入口点处能被直接访问,以确保调试器能够向系统的其余部分请求供电.这个GPR必须是以下之一:
- 包含在ROM表中的GPR.
- 一个单独的GPR,当ROM可以访问时,它总是可以访问.
图A1-8展示了一个包含GPR的ROM表的例子.
ROM表中的电源控制寄存器可用于发出电源请求:
- 调试电源控制寄存器
DBGPCR<n>
可为最多32个调试电源域申请电源. - 系统电源控制寄存器
SYSPCR<n>
可为最多32个系统电源域申请电源.
更多有关内容请见Register descriptions on page D4-329.