Armv8-A external debug
- Armv8-A debug模型
- 一,外部调试 External debug 简介
- 二,Debug state
- 2.1 Debug state的进入与退出
- 三,DAP,Debug Access Port
- 3.1 EDSCR, External Debug Status and Control Register
- 调试状态标识,STATUS, bits [5:0]
- 错误累积标识,ERR, bit [6]
- SError pending标识位,A, bit [7]
- 异常等级和执行状态,RW, bits [13:10]
- 异常等级,EL, bits [9:8]
- 中止运行并调试使能,HDE, bit [14]
- EDECR,External Debug Execution Control Register
- SS, bit [2]
- RCE, bit [1]
- OSUCE, bit [0]
Armv8-A debug模型
ARMv8-A架构支持两种debug模型:self-host debug 和 external debug。
- Self-host debug (自主机调试),调试器运行在被调试的CPU内部,调试器代码可以是 应用程序、内核、操作系统以及hypervisor。比如我们常见的GDB调试,就是使用self-host debug模型。Debug exception就是自主机调试的基础,调试器通过代码来控制debug 逻辑单元,从而产生debug 事件,而这些debug事件又会进一步产生debug 异常。笔者将会下篇博文中对self-host debug 模型进行详细介绍。
- External debug (外部调试),调试器在被调试的CPU外部。Debug state是 外部调试 模型的基础。调试器控制debug 逻辑单元产生debug 事件,而这些debug事件又会导致CPU进入Debug state(调试状态)。
本文主要介绍Armv8-A 架构下的 外部调试(external debug)模型 。
一,外部调试 External debug 简介
Armv8-A 的外部调试模型 的最大特点就是调试器位于 CPU 外部,这个外部的调试器通过debug 接口比如JTAG,与被调试的CPU相连,可以控制CPU进行如下操作:
- 当异常事件发生时,停止程序运行。
- 检查 或者 改变 CPU 架构性的寄存器的状态。
- 控制CPU 执行指令,去访问内存。
如下图所示,外部的debugger可以通过配置一些调试逻辑单元里的寄存器(debug register file),触发一个debug 事件,或者也可以让调试逻辑单元发出一个debug 停止请求(debug halt 或者 debug restart)的信号给CPU,进而控制CPU进入Debug state。
如下图所示,为一个标准的external debug 工作流程:
- 外部PC主机连接着一个外部调试器,同时主机上在运行控制调试器的应用程序
- 调试器通过debug 接口,比如JTAG,连接到处理器,与处理器的调试逻辑单元进行交互,控制处理器。
在debug state下,处理器在ITR(Instruction Transfer Register)中执行指令,外部调试器可以通过外部调试接口,往ITR中插入指令。DCC(Debug Communication Channel ) 则用于处理器和外部调试器进行通信的模块。
二,Debug state
上文讲过,外部调试模型的基础就是debug state,当debug事件发生时,外部调试器会控制调试逻辑单元进入调试状态。调试状态(debug state)又称为 halting debug state(停止调试状态)。当处理器进入debug state时,会按顺序发生以下操作:
- 处理器会停止执行位于PC寄存器中的地址上的指令,并且调试器通过外部调试接口开始控制处理器。
- 调试器通过外部调试接口,使用 ITR (Instruction Transfer Register)向处理器传输指令,让其执行,其中包括:
-
- 通过ITR让处理器执行指令,调试器可以读写 处理器架构内的寄存器,比如通用寄存器、系统寄存器以及浮点寄存器等等。
-
- 通过ITR让处理器执行指令,调试器还可以让处理器去访问内存。
- DCC 中的DTR(Data Transfer Registers)可以被外部调试接口以及系统寄存器接口访问,并且DCC在处理器和外部调试器之间交换数据起到了重要作用。
- 在调试状态下,处理器无法处理中断。
2.1 Debug state的进入与退出
当处理器进入调试状态时,会发生:
- 处理器在未进入调试状态之前的PSTATE的值,将会被存储在DSPSR(Debug Saved Program
Status Register)寄存器当中。就如同进入异常前将PSTATE保存到SPSR中一样。 - 将之后重新开始的地址(从调试状态退出后,继续执行指令的地址)保存到调试链接寄存器Debug Link Register (DLR).中。就如同进入异常处理时的ELR寄存器中一样。
- 处理器停止执行PC寄存器指向的指令。
- 中断将不再被处理。
- 外部调试器将接管处理器。
当处理器处于调试状态时,外部调试器可以:
- 查看并修改 内存空间以及架构性寄存器上的内容,包括DLR和DSPSR。
- 使用ITR向处理器传递指令让处理器执行。
- 使用DCC与处理器之间进行数据交互。
- 通过DCPS和DRPS指令,改变处理器的异常等级。
- 通过触发一个重新启动的请求可以离开调试状态。
当外部调试器发出了重新启动的请求,处理器将会离开调试状态,当处理器离开调试状态时,会发生:
- 将DLR中的地址恢复到PC寄存器当中。
- 将DSPSR寄存器保存的状态恢复到PSTATE中。
- 处理器继续从当前PC所指向的指令开始执行。
下图描述了当处理器在正常执行代码时,进入调试状态和离开调试状态的流程:
外部调试模型通常会用于:
- 点亮硬件系统,hardware bring-up: 在系统开发阶段,硬件系统第一次被启动的时候,一些软件功能还不健全甚至不存在,所以需要外部调试器来接管硬件系统。
- 调试深度嵌入在系统中的处理器。
三,DAP,Debug Access Port
在外部调试模型中,外部调试器可以通过外部调试接口来访问debug 寄存器,这意味着访问外部调试接口的方式是由架构实现定义的。在大多数ARMv8-A系统中,都会包含一个调试访问端口(DAP),处理器外部的调试器可以用DAP来访问外部调试接口。此外,若是片上外部调试器(On-chip external debuggers),比如使用一个处理器来调试另一个处理器,可以使用内存映射接口(memory mapped interface)来访问外部调试接口。如下图所示,为使用DAP来访问外部调试接口的示例,通过DAP,不仅可以访问处理器的调试逻辑单元(ITR和DCC),还能绕过处理器,直接访问内存系统:
外部调试寄存器,又称为中止模式调试寄存器(halt mode debug registers),通常以ED开头,比如EDSCR和EDECR。
3.1 EDSCR, External Debug Status and Control Register
外部调试状态和控制寄存器EDSCR,是处理器调试实现当中的主控寄存器,下图为EDSCR寄存器的字段划分示意图:
下面介绍EDSCR的几个常用的字段:
调试状态标识,STATUS, bits [5:0]
通过EDSCR的STATUS字段,可以知道处理器当前处于何种调试状态:
错误累积标识,ERR, bit [6]
调试错误累积标识位,在调试状态和出现DTR或EDITR上任何信号溢出或欠运行(overrun or underrun)的异常时,此位被设置为1。
SError pending标识位,A, bit [7]
SError中断的pending标识,在调试模式下,用于指示是否有挂起的SError 中断(pending):
如果HCR_EL2.{AMO, TGE} = {1, 0},EL2在当前安全状态下被使能,并且处理器运行在EL0或EL1下,表面是一个虚拟的SError 中断。
否则,将是一个物理的SError中断:
- 0b0 No SError interrupt pending.
- 0b1 SError interrupt pending.
调试器可以读取EDSCR寄存器来检查当前处理器在没有进一步执行指令的情况下,是否收到了SError中断(pending),一个pending的SError可能表明了从目标内存系统上获取到的数据已丢失或者错误。
异常等级和执行状态,RW, bits [13:10]
通过RW字段,可以知道当前处理器的异常等级和执行状态
异常等级,EL, bits [9:8]
在调试状态下,EL字段表明了当前处理器的异常等级。
中止运行并调试使能,HDE, bit [14]
EDSCR的HDE为1时,处理器可以被Breakpoint, Watchpoint 以及Halt Instruction等debug event 打断,进入调试状态。
- 0b0 Halting disabled for Breakpoint, Watchpoint and Halt Instruction debug events.
- 0b1 Halting enabled for Breakpoint, Watchpoint and Halt Instruction debug events
EDECR,External Debug Execution Control Register
EDECR寄存器可以控制中止处理器的各种调试事件(Halting debug events)。
SS, bit [2]
EDECR寄存器的SS字段可以控制Halting step debug event是否能中止处理器的运行:
- 0b0 Halting step debug event disabled.
- 0b1 Halting step debug event enabled.
如果在非调试状态下改变EDECR.SS的值,其行为时不可预测的。
If the value of EDECR.SS is changed when the PE is in Non-debug state, behavior is CONSTRAINED
RCE, bit [1]
EDECR寄存器的RCE字段可以控制Reset catch debug event是否能中止处理器的运行:
- 0b0 Reset Catch debug event disabled.
- 0b1 Reset Catch debug event enabled.
OSUCE, bit [0]
EDECR寄存器的OSUCE字段可以控制OS unlock catch debug event是否能中止处理器的运行:
- 0b0 OS Unlock Catch debug event disabled.
- 0b1 OS Unlock Catch debug event enabled.
Armv8-A external debug