RISC-V外部调试说明
系统概览
平台是由一个或多个元件组成的单个集成电路。有些组件可能是RISC-V内核,而其他组件可能具有不同的功能。通常,它们都将连接到单个系统总线。单个RISC-V核心包含一个或多个硬件线程,称为hart。
用户与运行调试器(如gdb)的调试主机(如笔记本电脑)交互。调试器与调试转换器(例如OpenOCD,它可能包括一个硬件驱动程序)通信,以与调试传输硬件(例如Olimex USB-JTAG适配器)通信。调试传输硬件将调试主机连接到平台的调试传输模块(Debug Transport Module, DTM)。DTM使用调试模块接口(DMI)提供对一个或多个调试模块(dm)的访问。
平台中每个hart都由一个DM控制。对hart-DM映射没有进一步的限制,但通常单个核心中的所有hart都由同一个DM控制。在大多数平台中,只有一个DM控制平台中的所有hart。
调试模块DM
调试模块接口DMI
调试模块从属于称为调试模块接口(DMI)的总线。总线的主人是调试传输模块(Debug Transport Module)。调试模块接口可以是一个普通的总线,有一个主总线和一个从总线,也可以使用功能更全面的总线,如TileLink或AMBA高级外围总线。
DMI使用7到32位地址位。如果在这个DMI上有额外的DM,DMI地址空间中下一个DM的基址在nextdm中给出。调试模块自己的状态和寄存器应该只在上电时重置,而dmcontrol中的dmactive为0。如果dmactive为1,即使会引起CSRs被清零,所有hart在系统重置期间也要保持halt状态。
重置控制
调试模块控制一个全局复位信号ndmreset(非调试模块复位),它可以复位或保持复位平台中的每个组件,除了调试模块和调试传输模块。
选择hart
一个单一的DM可以管理高达2^20个hart。
要枚举所有hart,调试器必须首先通过将所有hart写入hartsel(假设最大大小)并回读值来确定HARTSELLEN,以查看实际设置了哪些位。然后,它从0开始选择每个hart,直到在dmstatus中anynonexistent为1,或者达到最高索引(取决于HARTSELLEN)。
抽象命令
DM支持一组抽象命令,其中大部分是可选的。根据实现的不同,调试器可能能够执行一些抽象命令,即使所选的hart没有停止。调试器只能通过尝试特定状态下的特定hart支持哪些抽象命令,然后查看abstractcs中cmderr以确定它们是否成功。
如果命令接受参数,调试器必须在写入命令之前将它们写入数据寄存器。
每个抽象命令都是32位值。前8位包含cmdtype,它决定了命令的类型。
| cmdtype | Command |
|---|---|
| 0 | Access Register |
| 1 | Quick Access |
| 2 | Access Memory |
Access Register
3.6.1.1 Access Register
遵循以下操作顺序:
- 若write为0且transfer为1,则将regno指定的寄存器的数据拷贝到数据区arg0中,并执行从m模式读取该寄存器时发生的任何副作用。
- 若write为1且transfer为1,则将数据区arg0的数据拷贝到regno指定的寄存器中,并执行从m模式写入该寄存器时发生的任何副作用。
- 若aarpostincrement为1,则将增加regno。
- 若postexec为1,执行Program Buffer.
抽象寄存器号表
| 地址范围 | 说明 |
|---|---|
| 0x0000 - 0x0fff | CSRs,可以通过dpc访问PC |
| 0x1000 - 0x101f | GPRs |
| 0x1020 - 0x103f | 浮点寄存器 |
| 0xc000 - 0xffff | 保留给非标扩展和内部使用的 |
Quick Access
3.6.1.2 Quick Access
遵循以下操作顺序:
- 若hart已经暂停,命令将会设置cmderr为”halt/resume”并不会继续执行。
- 暂停hart。若hart因某些其他原因(如breakpoint)暂停,命令将会设置cmderr为”halt/resume”并不会继续执行。
- 执行Program Buffer。若发生异常,cmderr会被设置为”exception”并且program buffer结束执行,但快速访问命令会继续。
- 恢复hart。
Access Memory
3.6.1.3 Access Memory
遵循以下操作顺序:
- 若write为0,从arg1指定的内存位置拷贝数据到数据区arg0中。
- 若write为1,从数据区arg0拷贝数据到arg1指定的内存位置中。
- 若aampostincrement为1,则将增加arg1.
若任何操作失败,设置cmderr并不会执行任何剩余步骤。
程序缓冲区
3.7 Program Buffer
为支持在已停止的hart上执行任意指令,调试模块可以包括程序缓冲区,调试器可以将小程序写入其中。
调试器可以将一个小程序写入程序缓冲区,然后使用Access Register抽象命令执行它一次,命令中postexec位为1。调试器可以编写任何它喜欢的程序(包括跳出程序缓冲区),但是程序必须以ebreak或c.ebreak结束。
若progbufsize为1,则impebreak必须为1. 程序缓冲区可容纳一条32位或16位指令,所以在这种情况下,调试器必须只写一条指令,而不管它的大小。
执行程序缓冲区可能会破坏dpc。如果是这种情况,必须可以使用抽象命令读取/写入dpc,而不设置postexec。调试器必须尝试在停止和执行程序缓冲区之间保存dpc,然后在离开调试模式之前恢复dpc。
状态概览
下图显示了运行/停止调试期间hart经过的状态的概念视图,这些状态受到dmcontrol、abstractcs、abstractauto和command的不同字段的影响。
系统总线访问
3.9 System Bus Access
调试器可以使用Program Buffer或Access Memory抽象命令从hart的角度访问内存。一个调试模块也可以包括一个System Bus Access块来提供内存访问而不涉及hart,而不管是否实现了Program Buffer。
System Bus Access块支持8, 16, 32, 64和128位访问。下表显示在sbdata中每个访问大小可以访问的位。
| 访问大小 | 数据位 |
|---|---|
| 8 | sbdata0位7:0 |
| 16 | sbdata0位15:0 |
| 32 | sbdata0 |
| 64 | sbdata1, sbdata0 |
| 128 | sbdata3, sbdata2, sbdata1, sbdata0 |
DM寄存器
3.12 Debug Module Registers
本节中描述的寄存器是通过DMI总线访问的。每个DM都有一个基址(第一个DM为0)。下面的寄存器地址是这个基址的偏移量。
调试模块调试总线寄存器表
| 地址 | 名称 |
|---|---|
| 0x04 | Abstract Data 0 (data0) |
| 0x0f | Abstract Data 11 (data11) |
| 0x10 | Debug Module Control (dmcontrol) |
| 0x11 | Debug Module Status (dmstatus) |
| 0x12 | Hart Info (hartinfo) |
| 0x13 | Halt Summary 1 (haltsum1) |
| 0x14 | Hart Array Window Select (hawindowsel) |
| 0x15 | Hart Array Window (hawindow) |
| 0x16 | Abstract Control and Status (abstractcs) |
| 0x17 | Abstract Command (command) |
| 0x18 | Abstract Command Autoexec (abstractauto) |
| 0x19 | Configuration String Pointer 0 (confstrptr0) |
| 0x1a | Configuration String Pointer 1 (confstrptr1) |
| 0x1b | Configuration String Pointer 2 (confstrptr2) |
| 0x1c | Configuration String Pointer 3 (confstrptr3) |
| 0x1d | Next Debug Module (nextdm) |
| 0x20 | Program Buffer 0 (progbuf0) |
| 0x2f | Program Buffer 15 (progbuf15) |
| 0x30 | Authentication Data (authdata) |
| 0x34 | Halt Summary 2 (haltsum2) |
| 0x35 | Halt Summary 3 (haltsum3) |
| 0x37 | System Bus Address 127:96 (sbaddress3) |
| 0x38 | System Bus Access Control and Status (sbcs) |
| 0x39 | System Bus Address 31:0 (sbaddress0) |
| 0x3a | System Bus Address 63:32 (sbaddress1) |
| 0x3b | System Bus Address 95:64 (sbaddress2) |
| 0x3c | System Bus Data 31:0 (sbdata0) |
| 0x3d | System Bus Data 63:32 (sbdata1) |
| 0x3e | System Bus Data 95:64 (sbdata2) |
| 0x3f | System Bus Data 127:96 (sbdata3) |
| 0x40 | Halt Summary 0 (haltsum0) |
dmstatus, 0x11
3.12.1 Debug Module Status (dmstatus, at 0x11)
这个寄存器报告整个调试模块以及由hasel所选hart的状态。它的地址在将来不会改变,因为它包含了version。
整个寄存器是只读的。
dmcontrol, 0x10
3.12.2 Debug Module Control (dmcontrol, at 0x10)
这个寄存器控制整个调试模块以及由hasel所选的hart。
在本文档中,我们提到hartsel,它是hartselhi和hartsello的组合。虽然规范允许20个hartsel位,但实现可能会选择实现少于这个数。hartsel的实际宽度被称为HARTSELLEN。它最少为0,最多为20。调试器应该通过将所有的1写入HARTSELLEN(假设最大大小)并回读值以查看实际设置了哪些位来发现HARTSELLEN。
在任何给定的写操作中,调试器最多只能将1写入以下位中的一个:resumereq、hartreset、ackhavereset、setresethaltreq和clrresethaltreq。其他的必须写成0。
resethaltreq是每个hart可选内部状态位,不能读取,但可以使用setresethaltreq和clrresethaltreq写入。
hartinfo, 0x12
3.12.3 Hart Info (hartinfo, at 0x12)
这个寄存器能获取hartsel选择的hart的信息。
这个寄存器是可选的。若它不可用它会读到全0。
如果包含这个寄存器,调试器可以通过编写显式访问data或dscratch寄存器的程序来对程序缓冲区做更多的工作。
hawindowsel, 0x14
3.12.4 Hart Array Window Select (hawindowsel, at 0x14)
hawindowsel有效可写位取决于具体实现,最多为15位。比如单个DM支持48个hart,则此寄存器只有bit0可以写入,其余位均为0.
hawindow, 0x15
3.12.5 Hart Array Window (hawindow, at 0x15)
hart数组掩码寄存器,与hawindowsel一起选择hart数组。比如bit0代表hawindowsel * 32索引的hart,bit31代表hawindowsel * 32 + 31索引的hart。
abstractcs, 0x16
3.12.6 Abstract Control and Status (abstractcs, at 0x16)
当一个抽象命令正在执行时,写这个寄存器会造成cderr被设置为1(忙),如果它是0.
支持RV32,datacount至少为1;支持RV64,至少为2;支持RV128,至少为4.
command, 0x17
3.12.7 Abstract Command (command, at 0x17)
写这个寄存器会造成相关抽象命令被执行。
当一个抽象命令正在执行时,写这个寄存器会造成cderr被设置为1(忙),如果它是0.
如果cmderr为非0,写这个寄存器会被忽略。
abstractauto, 0x18
3.12.8 Abstract Command Autoexec (abstractauto, at 0x18)
这个寄存器是可选的。包含它允许更有效的突发访问。调试器可以通过设置位并读取它们来检测它是否被支持。
当一个抽象命令正在执行时,写这个寄存器会造成cderr被设置为1(忙),如果它是0.
confstrptr0, 0x19
3.12.9 Configuration String Pointer 0 (confstrptr0, at 0x19)
当设置confstrptrvalid时,读取该寄存器将返回配置字符串指针的第31:0位。读取其他的confstrptr寄存器返回地址的上位。
当实现系统总线主控时,这必须是一个可以与系统总线访问模块一起使用的地址。否则,这必须是一个可以用来访问ID0的hart的配置字符串的地址。
如果confstrptrvalid为0,则confstrptr寄存器保存标识符信息,该信息在本文档中没有进一步指定。
nextdm, 0x1d
3.12.10 Next Debug Module (nextdm, at 0x1d)
如果在DMI上有超过一个DM,这个寄存器包含链中下一个DM的基地址,如果是链中最后一个则为0.
data0, 0x04
3.12.11 Abstract Data 0 (data0, at 0x04)
data0到data11是基本的读/写寄存器,可以通过抽象命令读取或更改。dataccount表示实现了多少个,从data0开始,依次递增。
progbuf0, 0x20
3.12.12 Program Buffer 0 (progbuf0, at 0x20)
progbuf0到progbuf15提供对可选程序缓冲区的读/写访问。progbufsize表示从progbuf0开始实现的数目,依次递增。
authdata, 0x30
3.12.13 Authentication Data (authdata, at 0x30)
这个寄存器作为一个32位的串行端口进出认证模块。
当authbusy为0时,调试器可以通过读取或写入该寄存器与身份验证模块通信。没有单独的机制来指示溢出/下溢。
haltsum0, 0x40
3.12.14 Halt Summary 0 (haltsum0, at 0x40)
这个只读寄存器中的每个位表示一个特定的hart是否停止。不可用/不存在的hart不被认为是停止的。
LSB代表hart hartsel[19:5],5'h0的暂停状态,MSB代表harthartsel[19:5],5'h1f的暂停状态。
haltsum1, 0x13
3.12.15 Halt Summary 1 (haltsum1, at 0x13)
这个只读寄存器中的每个位表示一组(32个)hart是否停止。不可用/不存在的hart不被认为是停止的。
这个寄存器不能出现在少于33个hart的系统中。
LSB代表一组harthartsel[19:10],10'h0到harthartsel[19:10],10'h1f的暂停状态。MSB代表一组harthartsel[19:10],10'h3e0到harthartsel[19:10],10'h3ff的暂停状态。
haltsum2, 0x34
3.12.16 Halt Summary 2 (haltsum2, at 0x34)
这个只读寄存器中的每个位表示一组(1024个)hart是否停止。不可用/不存在的hart不被认为是停止的。
这个寄存器不能出现在少于1025个hart的系统中。
LSB代表一组harthartsel[19:15],15'h0到harthartsel[19:15],15'h3ff的暂停状态。MSB代表一组harthartsel[19:15],15'h7c00到harthartsel[19:15],15'h7fff的暂停状态。
haltsum3, 0x35
3.12.17 Halt Summary 3 (haltsum3, at 0x35)
这个只读寄存器中的每个位表示一组(32768个)hart是否停止。不可用/不存在的hart不被认为是停止的。
这个寄存器不能出现在少于32769个hart的系统中。
LSB代表一组hart20'h0到hart20'h7fff的暂停状态。MSB代表一组hart20'hf8000到hart20'hfffff的暂停状态。
sbcs, 0x38
3.12.18 System Bus Access Control and Status (sbcs, at 0x38)
sbaddress0, 0x39
3.12.19 System Bus Address 31:0 (sbaddress0, at 0x39)
如果sbasize为0,则这个寄存器不存在。
如果sberror为0,sbbusyerror为0,sbreadonaddr为1,然后开始向该寄存器写入以下内容:
- sbbusy置位。
- 从sbaddress的新值执行一次总线读取。
- 如果读成功且sbautoincrement为1,增加sbaddress。
- sbbusy清零。
sbaddress1, 0x3a
3.12.20 System Bus Address 63:32 (sbaddress1, at 0x3a)
如果sbasize少于33,则这个寄存器不存在。
sbaddress2, 0x3b
3.12.21 System Bus Address 95:64 (sbaddress2, at 0x3b)
如果sbasize少于65,则这个寄存器不存在。
sbaddress3, 0x37
3.12.22 System Bus Address 127:96 (sbaddress3, at 0x37)
如果sbasize少于97,则这个寄存器不存在。
sbdata0, 0x3c
3.12.23 System Bus Data 31:0 (sbdata0, at 0x3c)
如果sbc中的所有saccess位都是0,那么这个寄存器不存在。
对这个寄存器写入开始如下:
- sbbusy置位。
- 对sbdata的新值执行总线写入到sbaddress。
- 如果写成功且设置了sbautoincrement,增加sbaddress。
- sbbusy清零。
从这个寄存器读取开始如下:
- 返回数据。
- sbbusy置位。
- 如果设置了sbreadondata,则从saddress中包含的地址执行一次系统总线读取,将结果放入sbdata中。
- 如果设置了sbautoincrement,增加sbaddress。
- sbbusy清零。
sbdata1, 0x3d
3.12.24 System Bus Data 63:32 (sbdata1, at 0x3d)
如果sbaccess64和sbaccess128为0,那么这个寄存器不存在。
sbdata2, 0x3e
3.12.25 System Bus Data 95:64 (sbdata2, at 0x3e)
只有当sbaccess128为1时,这个寄存器才存在。
sbdata3, 0x3f
3.12.26 System Bus Data 127:96 (sbdata3, at 0x3f)
只有当sbaccess128为1时,这个寄存器才存在。
RISC-V调试
调试模式
调试模式是一种特殊的处理器模式,仅在hart暂停用于外部调试时使用。
当从可选的程序缓冲区执行代码时,hart保持在调试模式,并适用以下内容:
- 所有操作都在机器模式特权级别执行,除了根据mprven可以忽略处于状态的MPRV。
- 所有中断(包括NMI)被屏蔽。
- 异常不更新任何寄存器。包括cause, epc, tval, dpc和mstatus。它们终止程序缓冲区的执行。
- 如果一个触发器匹配上,则不采取任何操作。
- 计数器可能会停止,这取决于dcsr中的stopcount。
- 计时器可能会停止,这取决于dcsr中的stoptime。
- wfi指令起着nop的作用。
- 几乎所有改变特权级别的指令都有未定义的行为。这包括ecall、mret、sret和uret。(要更改特权级别,调试器可以在dcsr中写入prv)。唯一的例外是ebreak。当在调试模式下执行该命令时,它会再次停止hart,但不会更新dpc或dcsr。
- 完成Program Buffer的执行被认为是fence指令的输出。
- 如果所有的控制转移指令的目的地在程序缓冲区中,它们都可能被视为非法指令。如果其中一条指令是非法指令,那么所有这些指令都必须是非法指令。
- 如果控制转移指令的目的地在程序缓冲区之外,则所有控制转移指令都可能被视为非法指令。如果其中一条指令是非法指令,那么所有这些指令都必须是非法指令。
- 依赖于PC值的指令(例如auipc)可能作为非法指令。
- 有效的XLEN是DXLEN。
等待中断指令
如果在wfi执行时请求暂停,则hart必须离开已停止状态,完成该指令的执行,然后进入调试模式。
单步调试
调试器可以使暂停的hart执行一条指令,然后在设置resumereq之前通过设置step重新进入调试模式。
如果执行或获取该指令导致异常,则在PC更改为异常处理程序并更新相应的tval和cause寄存器后立即重新进入调试模式。
如果执行或获取指令导致触发器触发,则在触发器触发后立即重新进入调试模式。在这种情况下,cause被设置为2(trigger)而不是4(single step)。指令是否执行取决于触发器的具体配置。
如果被执行的指令导致PC改变到一个地址,在这个地址中指令获取会导致异常,那么这个异常直到下一次hart被恢复时才会发生。
类似地,新地址的触发器在hart实际尝试执行该指令之前不会触发。
如果正在跳过的指令是wfi并且通常会使hart停止,那么该指令将被视为nop。
重置
如果在hart从复位状态出来时断言了暂停信号(由hart的调试模块中的暂停请求位驱动)或resethaltreq, hart必须在执行任何指令之前进入调试模式,但在执行任何初始化之后,通常会在执行第一个指令之前发生
dret指令
为了从调试模式返回,定义了一条新指令:dret。编码为0x7b200073。在支持此指令的硬件上,在调试模式下执行dret会将pc更改为存储在dpc中的值。将当前权限级别更改为dcsr中prv指定的权限级别。hart不再处于调试模式。
核调试寄存器
| 地址 | 名称 |
|---|---|
| 0x7b0 | Debug Control and Status (dcsr) |
| 0x7b1 | Debug PC (dpc) |
| 0x7b2 | Debug Scratch Register 0 (dscratch0) |
| 0x7b3 | Debug Scratch Register 1 (dscratch1) |
dcsr, 0x7b0
4.8.1 Debug Control and Status (dcsr, at 0x7b0)
dpc, 0x7b1
4.8.2 Debug PC (dpc, at 0x7b1)
dscratch0, 0x7b2
4.8.3 Debug Scratch Register 0 (dscratch0, at 0x7b2)
dscratch1, 0x7b3
4.8.4 Debug Scratch Register 1 (dscratch1, at 0x7b3)
虚拟调试寄存器
虚拟寄存器是一种不直接存在于硬件中的寄存器,但调试器将其显示为存在的寄存器。调试软件应该实现它们,但是硬件可以跳过这一节。虚拟寄存器的存在是为了让用户访问不属于标准调试器的功能,而不需要他们在调试器访问这些寄存器时仔细修改调试寄存器。
priv
4.9.1 Privilege Level (priv, at virtual)
用户可以读取此寄存器以检查hart停止时运行的特权级别。用户可以写这个寄存器来更改hart恢复时运行的特权级别。
| 编码 | 特权等级 |
|---|---|
| 0 | User/Application |
| 1 | Supervisor |
| 3 | Machine |
触发器模块
触发器可以导致断点异常、进入调试模式或跟踪操作,而无需执行特殊指令。这使得它们在从ROM中调试代码时非常宝贵。
触发器在调试模式下不会触发。
调试器可以构建所有触发器及其特性的列表,如下所示:
- 将0写入tselect。
- 回读tselect并检查它是否包含写入的值。如果不是,则退出循环。
- 读tinfo。
- 如果导致异常,调试器必须读取tdata1以发现类型。(如果type为0,则此触发器不存在。退出循环。)
- 如果info为1,则此触发器不存在。退出循环。
- 否则,所选触发器支持info中发现的类型。
- 重复,增加tselect中的值。
本地M-Mode触发器
触发器可用于本机调试。在一个功能齐全的系统上,触发器将使用u或s来设置,当触发它们时,可能会导致一个断点异常被捕获到一个更特权的模式。也可以将触发器本地设置为在M模式下触发。在这种情况下,没有更高的特权模式可以捕获。当这样的触发器在陷阱处理程序中导致断点异常时,这将使系统无法恢复正常执行。
简单的解决方案是在“M模式”和MIE在mstatus为0的状态下,让硬件防止触发器触发action=0。它的限制是,当用户想要触发触发器时,可能会在其他时间禁用中断。
触发器寄存器
这些寄存器是CSR,可以使用RISC-V csr操作码访问,也可以选择使用抽象调试命令。
action编码表
| 值 | 描述 |
|---|---|
| 0 | 引发断点异常。(当软件想要在没有外部调试器的情况下使用触发模块时使用。) |
| 1 | 进入调试模式。(仅当触发器的dmode为1时支持。) |
| 2 - 5 | 保留供trace规范使用。 |
| other | 保留以备将来使用。 |
触发器寄存器表
| 地址 | 名称 |
|---|---|
| 0x7a0 | Trigger Select (tselect) |
| 0x7a1 | Trigger Data 1 (tdata1) |
| 0x7a1 | Match Control (mcontrol) |
| 0x7a1 | Instruction Count (icount) |
| 0x7a1 | Interrupt Trigger (itrigger) |
| 0x7a1 | Exception Trigger (etrigger) |
| 0x7a2 | Trigger Data 2 (tdata2) |
| 0x7a3 | Trigger Data 3 (tdata3) |
| 0x7a3 | Trigger Extra (RV32) (textra32) |
| 0x7a3 | Trigger Extra (RV64) (textra64) |
| 0x7a4 | Trigger Info (tinfo) |
| 0x7a5 | Trigger Control (tcontrol) |
| 0x7a8 | Machine Context (mcontext) |
| 0x7aa | Supervisor Context (scontext) |
tselect, 0x7a0
5.2.1 Trigger Select (tselect, at 0x7a0)
这个寄存器确定哪个触发器可以通过其他触发器寄存器访问。可访问触发器集必须从0开始,并且是连续的。
tdata1, 0x7a1
5.2.2 Trigger Data 1 (tdata1, at 0x7a1)
tdata2, 0x7a2
5.2.3 Trigger Data 2 (tdata2, at 0x7a2)
tdata3, 0x7a3
5.2.4 Trigger Data 3 (tdata3, at 0x7a3)
tinfo, 0x7a4
5.2.5 Trigger Info (tinfo, at 0x7a4)
tcontrol, 0x7a5
5.2.6 Trigger Control (tcontrol, at 0x7a5)
mcontext, 0x7a8
5.2.7 Machine Context (mcontext, at 0x7a8)
scontext, 0x7aa
5.2.8 Supervisor Context (scontext, at 0x7aa)
mcontrol, 0x7a1
5.2.9 Match Control (mcontrol, at 0x7a1)
当type为2时,这个寄存器可以作为tdata1访问。
icount, 0x7a1
5.2.10 Instruction Count (icount, at 0x7a1)
当type为3时,这个寄存器可以作为tdata1访问。
itrigger, 0x7a1
5.2.11 Interrupt Trigger (itrigger, at 0x7a1)
当type为4时,这个寄存器可以作为tdata1访问。
etrigger, 0x7a1
5.2.12 Exception Trigger (etrigger, at 0x7a1)
当type为5时,这个寄存器可以作为tdata1访问。
textra32, 0x7a3
5.2.13 Trigger Extra (RV32) (textra32, at 0x7a3)
textra64, 0x7a3
5.2.14 Trigger Extra (RV64) (textra64, at 0x7a3)
调试传输模块DTM
调试传输模块通过一个或多个传输(例如JTAG或USB)提供对DM的访问。
单个平台中可能有多个dtm。理想情况下,与外部世界通信的每个组件都包含DTM,允许通过平台支持的每种传输对平台进行调试。例如,USB组件可以包含DTM。这样就可以轻松地通过USB调试任何平台。所需要的就是已经在使用的USB模块也可以访问调试模块接口。
JTAG调试传输模块
这个调试传输模块是基于一个正常的JTAG测试访问端口(TAP)。通过首先使用JTAG指令寄存器(IR)选择一个JTAG寄存器,然后通过JTAG数据寄存器(DR)访问它,JTAG TAP允许访问任意JTAG寄存器。
JTAG DTM寄存器
用作DTM的JTAG抽头必须具有至少5位的IR。当TAP复位时,IR必须默认为00001,选择IDCODE指令。调试器可能使用的唯一常规JTAG寄存器是BYPASS和IDCODE,但是该规范为许多其他标准JTAG指令留下了IR空间。未实现指令必须选择BYPASS寄存器。
JTAG DTM TAP寄存器表
| 地址 | 名称 | 描述 |
|---|---|---|
| 0x00 | BYPASS | JTAG recommends this encoding |
| 0x01 | IDCODE | JTAG recommends this encoding |
| 0x10 | DTM Control and Status (dtmcs) | For Debugging |
| 0x11 | Debug Module Interface Access (dmi) | For Debugging |
| 0x12 | Reserved (BYPASS) | Reserved for future RISC-V debugging |
| 0x13 | Reserved (BYPASS) | Reserved for future RISC-V debugging |
| 0x14 | Reserved (BYPASS) | Reserved for future RISC-V debugging |
| 0x15 | Reserved (BYPASS) | Reserved for future RISC-V standards |
| 0x16 | Reserved (BYPASS) | Reserved for future RISC-V standards |
| 0x17 | Reserved (BYPASS) | Reserved for future RISC-V standards |
| 0x1f | BYPASS | JTAG requires this encoding |
IDCODE, 0x01
6.1.3 IDCODE (at 0x01)
当TAP状态机复位时,选择这个寄存器(在IR中)。其定义与IEEE标准1149.1-2013中的定义完全一致。
dtmcs, 0x10
6.1.4 DTM Control and Status (dtmcs, at 0x10)
在以后的版本中,这个寄存器的大小将保持不变,以便调试器始终可以确定DTM的版本。
dmi, 0x11
6.1.5 Debug Module Interface Access (dmi, at 0x11)
这个寄存器允许访问调试模块接口(DMI)。
在Update-DR中,DTM将启动op中指定的操作,除非op中报告的当前状态为sticky。 在Capture-DR中,DTM使用该操作的结果更新数据,如果当前操作不是sticky,则更新op。
BYPASS 0x1f
6.1.6 BYPASS (at 0x1f)
无效的1位寄存器。当调试器不想与此TAP通信时使用它。