高延海 樊 茂
(中国船舶集团有限公司第七二二研究所 武汉 430205)
近年来随着国家信息产业政策的推动,国产处理器发展势头迅猛,推出了包括申威、龙芯、飞腾在内的一系列国产处理器,覆盖了从嵌入式系统到高性能计算等各领域,自主可控水平得到了较大的提高。国产处理器的自主可控,在很大程度上还依赖于其生态的建设,调试开发工具是其中必要的一环。国产处理器一般只有处理器厂商提供的专用调试开发工具可供选择,而国外处理器普遍有第三方专业厂商为其提供调试开发工具,选择余地更大,功能更完善。因此国产处理器生态在调试开发工具这一环,相比国外处理器还有一定的差距。
申威处理器[1]依托国家“863”和“核高基”专项,十余年发展与积累过程中,历经三代核心的开发,在多个领域得到成功应用。对于申威处理器应用系统硬件和底层软件的调试,一般只能使用处理器厂商提供的JTAG调试工具。该调试工具提供了FLASH存储器编程、内存读写等功能,可以满足硬件调试和软件固化的基本需求,但也存在一些不足之处:调试工具的硬件为定制开发,成本较高;不能对JTAG底层通信协议进行调试,若JTAG通信故障则难以定位原因;技术细节封闭,用户无法在其基础上扩展功能。针对上述问题,设计了一种基于开源硬件的JTAG调试工具,可实现对申威421处理器应用系统硬件与底层软件的开发调试。
申威421处理器是64位字长的RISC架构高性能通用处理器[2],单芯片集成了4个申威Core3A核心,支持乱序发射、推测执行和双访存流水线技术[3]。处理器还集成了8MB的三级共享Cache、两路64位DDR3存储控制器、两路第三代标准PCI-E接口、维护接口以及符合IEEE1149.1标准的测试接口。
典型的申威421应用系统一般由处理器搭配ICH2桥片[4]构成。ICH2桥片通过一个8通道的PCI-E 2.0接口与申威421互连,可以为应用系统扩展PCI-E、USB、SATA等高速外设接口,以及UART、PS/2、I2C等传统的通用外设接口。ICH2桥片内部还集成了一个图形图像子系统及一个显存控制器,可以为应用系统提供集成显卡功能。ICH2桥片有比较多的配置参数,存储在外部的参数FLASH存储器中。图1是一个典型的申威421应用系统组成框图。
图1 申威421应用系统框图
JTAG技术即边界扫描测试技术,由联合测试行动组(JTAG)最初提出[5],并于 1990年形成了IEEE 1149.1标准,也称为JTAG标准。JTAG技术主要用于芯片的测试,若电路板上有支持JTAG功能的器件,JTAG技术也可用于对电路板进行测试[6]。
边界扫描技术需要在芯片内紧邻器件引脚处设置移位寄存器[7],从而使处于器件边界的信号可以通过扫描测试技术进行监视或控制。为了支持边界扫描,集成电路器件必须有4个专用的引脚:TCK、TMS、TDI和TDO。这4个引脚组成了测试访问端口(TAP),也称为JTAG端口。JTAG端口用于外部测试设备与器件内部的边界扫描逻辑进行通信。器件内边界扫描功能模块中包含有一个指令寄存器(IR)和一组数据寄存器(DR),可以通过JTAG端口对这些寄存器进行读写,以实现边界扫描测试功能。边界扫描功能模块的核心是一个TAP控制器,为一有限状态机,包含16个状态。通过TCK和TMS可以控制TAP状态的迁移,产生边界扫描逻辑的内部控制信号。TAP控制器状态迁移如图2所示。TDI和TDO用来对边界扫描逻辑中寄存器数据的移入、移出。
图2 TAP控制器状态图
JTAG端口初衷是用于对芯片进行测试,然而对于具有边界扫描测试功能的处理器,JTAG端口也往往用于对处理器应用系统进行调试。处理器应用系统的调试一般有ICE和OCD两种方案[8]。ICE方案需要为处理器设计专用的仿真器,模拟处理器的所有功能,成本极高,而且对于复杂处理器,实现起来非常困难。目前主流的是OCD方案。OCD即片上调试,需要在处理器内部添加一个专门的硬件模块,用于支持调试功能。该硬件模块能够访问处理器的内部资源,并有与外部调试设备进行通信的端口。为了减少硬件资源消耗,该通信端口往往与JTAG端口复用[9],因此从用户视角,就是通过JTAG端口对处理器进行调试。
申威421处理器具有符合IEEE 1149.1标准的JTAG端口,可以进行边界扫描测试及维护调试操作。申威421处理器JTAG端口的指令寄存器长度为 8位,除了有 BYPASS、IDCODE、SAMPLE/PRELOAD等标准指令外,还有两条自定义指令CHAINADDR和RUNSCAN。申威421的JTAG数据寄存器中,和JTAG调试相关的有两个寄存器:测试地址寄存器、调试接口寄存器。当给JTAG指令寄存器写入CHAINADDR指令后,即可对测试地址寄存器进行设置,选择调试接口寄存器作为SAMPLE/PRELOAD指令的操作对象。调试接口寄存器中包含数据、命令、目标寄存器、校验等位段,通过对该寄存器的读写实现与维护调试模块的通信,执行对处理器的所有维护调试操作,如图3所示。
图3 调试操作流程
申威421处理器的维护串口也可以对维护调试模块进行访问。维护串口的MT_RX_H信号必须外接上拉电阻,避免与JTAG端口同时对维护调试模块进行访问而发生冲突,无法进行正常的调试操作。
在设计硬件时,需要关注JTAG端口的信号完整性,特别是TCK的信号质量。JTAG数据的移位与采样都是通过TCK信号控制,TCK信号上的串扰、反射等信号质量问题,会造成JTAG数据误移位或误采样,甚至使TAP控制器状态错乱。在PCB设计时,JTAG连接器应尽量靠近处理器摆放,缩短JTAG信号线的长度。必要时还要通过端接、滤波等措施,改善JTAG信号的质量。另外JTAG调试电缆经常插拔,易受静电影响,信号线在靠近JTAG插座附近应使用TVS管等保护器件,避免处理器JTAG端口被静电损伤。
JTAG调试工具的硬件是连接PC主机与目标系统的JTAG控制器,负责产生符合IEEE 1149.1规范的JTAG信号时序。部分处理器厂商为推广自家的产品,开源了JTAG调试器的设计资料,如ARM的DAPLink,TI的XDS100系列等。申威处理器只需要标准的JTAG信号就可以进行调试,因此综合考虑成本与周期,以及避免不必要的重复投入,选择了开源的XDS100V2商业现货调试器作为JTAG调试工具的硬件平台。
XDS100V2调试器[10]用于TI公司的DSP、ARM等处理器产品的调试。TI公开了XDS100V2的所有设计资料,任何第三方厂家都可以根据公开的资料生产和销售XDS100V2调试器。XDS100V2硬件的核心是一片FTDI公司的FT2232芯片,可以实现USB接口到SPI、JTAG等同步串口的转换,设计紧凑,成本低廉。XDS100V2通过USB 2.0接口与主机通信,JTAG端口最高工作频率达15M,对大多数的调试操作性能可以满足要求。
在正式进行调试之前,对JTAG链路功能进行测试,性能进行摸底,能够排除JTAG链路中可能存在的故障,并使调试器以最高的性能工作,对顺利、高效地完成调试工作十分有益。对JTAG链路采用数据环回的方式进行测试。JTAG端口进行寄存器移位操作时,当寄存器中的数据全部移出后,若TAP控制器仍停留在Shift-IR或Shift-DR状态,接下来移出的将是从TDI移入的数据,即实现了数据环回。测试数据可以采用PRBS伪随机序列,也可以采用固件镜像等数据。
在数据环回测试的开始,首先复位TAP控制器,指令寄存器被初始化为 IDCODE[12],进行数据寄存器的移位操作移出的将是处理器ID。然后TAP控制器状态转换到Shift-DR状态,进行数据移位操作。最开始移出的32位数据与处理器ID比较,后面移出的数据与从TDI移入的数据进行比较,若出现数据不一致的情况,则中断测试,保存移出的数据,提示出错数据的位置,供测试人员进行分析。
经过测试,在目标开发板上,调试器可以稳定工作在15M的最高频率,远超XDS100V2标准的1M工作频率,也高于申威421手册中给出10M的工作频率,大大提高了调试工具性能的上限。
调试器与处理器建立连接,第一步要确认JTAG链路可以正常工作,第二步确认连接的是正确的目标处理器,第三步确认目标处理器处于正常的工作状态。以上三步都成功以后,则说明硬件已处于就绪状态,可以进行调试操作。JTAG标准中规定,Capture指令寄存器获取的值,最低两位必须是2’b01。因此第一步可以通过Capture指令寄存器,并判断指令寄存器的最低两位是否符合标准来实施。第二步可以通过IDCODE指令读取处理器ID,与申威处理器ID值0x0006a001比较来实现。第三步首先要将申威421处理器的JTAG端口置于维护调试模式,然后读取维护调试模块中的状态寄存器,获取处理器当前的运行状态。连接处理器的流程如图4所示。
图4 调试器连接处理器流程
4.3.1 申威421的FLASH存储器接口
申威421有SPI FLASH存储器接口,可以支持最大容量为16MB的FLASH存储器。启动时处理器从FLASH中读取硬件配置参数并加载固件。申威421的FLASH访问地址在I/O地址空间,并且地址不连续,每8个字节占用128字节的地址,因此处理器不能直接从FLASH中取指令运行,必须将FLASH中的代码加载到系统内存或内核Cache中才能运行。申威421内部有FLASH控制器,可自动生成编程、擦除等操作的信号时序。
4.3.2 影响调试效率的主要因素
主机与调试器间数据传送的组织方式,是影响调试效率的主要因素。主机与调试器间的USB口通过BULK方式传输数据[13],一次传输的数据量越大,则USB传输带宽的利用率就越高。如果频繁地进行短数据包通信,开销所占比例将大大增加,实际的传输速率将远远低于理想的速率。从图3中可以看到,申威处理器标准调试流程需要对调试指令的完成状态进行查询,以判断是否可向处理器发出下一条调试指令,这就决定了主机与调试器之间只能以短数据包进行通信,并且需要主机频繁地进行判断与干预,严重影响调试操作的效率。
4.3.3 高效的调试操作流程
由于常规调试操作流程的效率低,为了提高FLASH编程的速率,必须设计一个新的调试操作流程。新的调试流程中,发送调试指令不需要确认上一条调试指令的完成情况,在一个USB数据包中可一次传送多条调试指令给调试器。在调试指令之间,插入相应的延时指令和状态查询指令。指令数据包的格式如图5所示。
图5 JTAG指令数据包格式
延时指令就是保持TAP控制器在Run-Test-Idle状态下一定数量的TCK周期,用于给调试指令的执行留出一定的时间。如果延时短于调试指令执行所需时间,则其后的调试指令就会在上一条调试指令未完成的情况下发送给处理器。新的调试指令可能会被拒绝接收,也可能会影响上一条调试指令的正常执行。对于FLASH编程这样的调试操作,造成的最坏结果就是当前FLASH存储单元编程失败,而不会产生破坏性的后果,因此FLASH编程操作可以使用新流程。
主机会重新执行操作失败的调试指令。为了使调试指令尽可能一次成功完成,延时指令的延时需要大于调试指令执行所需的时间,但又要近可能的接近,这样既保证了成功率,也不降低效率。由于最初并不知道调试指令执行所需的确切时间,所以新流程中还需要实现延时的自适应调整。最开始设置一个较短的延时值,此后自动将延时周期数调整到最恰当的值。
延时周期的自适应调整需要结合查询指令来进行。查询指令用于查询相关调试指令的操作是否完成,与常规流程不同的是,JTAG调试器在执行完查询指令后,紧接着就执行下一条调试指令,中间不存在主机进行判断与干预的过程。主机在收到指令数据包中所有查询指令的查询结果后,对数据包中调试指令的执行情况进行判断,如果有调试指令未完成操作,则该调试指令以及此后的所有调试指令都将重新执行,并且增加延时指令的延时值。经过有限次的重传指令和增加延时,延时周期就可以调整到最佳值,如图6所示。
图6 高效的调试操作流程
经过实际运行比较,采用标准的调试操作流程,固化2M字节的BIOS到FLASH,需要近3min。而采用新的流程,同样的操作只需约20s。显然,新调试操作流程确实能够大幅提高调试操作的效率。
4.4.1 BIOS调试信息输出机制
在进行固件调试时,我们需要固件运行过程中输出一些文本调试信息以帮助调试。申威421处理器应用系统BIOS的调试信息不是通过串口或网口输出,而是按顺序写到一个固定的内存区域。厂家提供的调试工具只能在用户给出命令时,一次读取所有BIOS调试信息并显示,而不能实时显示BIOS运行过程中新增的调试信息。作为固件调试人员,自然希望固件调试信息能够像通过串口输出一样,可以即时显示,实时监测固件的运行状态。针对这个需求,为JTAG调试工具开发了BIOS调试信息实时显示功能。
4.4.2 实时显示调试信息
BIOS调试信息的显示是基于内存读取操作实现的。为实时显示新的调试信息,软件需要不断的对调试信息内存区域进行查询。在两次查询之间需要一定的时间间隔,这里设为100ms,对人的阅读来说不会有感觉,也避免了因USB端口操作太过密集而占用过多的处理器资源。最初从调试信息内存区域的起始地址开始查询。若查询到有新的调试信息,则连续向调试器发送内存读取指令,并在软件的文本窗口中显示新的调试信息,直到将新的调试信息全部读取并显示完毕,然后又从剩余的内存空间起始地址处开始反复进行间隔100ms的查询。
由于维护调试模块的内存读取指令以128字节为单位且地址对界,因此每次读取调试信息的操作所使用的地址必须是128字节对齐的,读回的128字节数据中一般还包含原来的调试信息。所以判断是否有新调试信息,需要记录原调试信息最后一个字符在128字节中的偏移地址,在该偏移地址之后有新增的不为0数据,才是新的调试信息。图7是对BIOS调试信息进行实时显示的基本工作流程。
图7 BIOS调试信息显示基本工作流程
BIOS调试信息实时显示功能的运行效果与通过串口输出调试信息基本相同,实际上由于JTAG端口更高的工作频率,比串口能更好地显示大量快速更新的调试信息。
本文基于开源JTAG调试器设计了申威421应用系统JTAG调试工具,可以实现内存读写、FLASH编程等必要的调试功能。该JTAG调试工具可以进行JTAG链路性能测试,让JTAG链路能够工作在实际的最高性能下,同时还实现了一定程度的JTAG链路故障诊断功能,改善了JTAG链路故障难以调试的现状。创新的调试指令执行流程,通过延时周期预测及自适应调整,大幅提高了调试操作的效率。由于硬件技术的开放,易于根据应用需求扩展功能,如BIOS调试信息的实时显示等。通过设计申威421应用系统JTAG调试工具,为国产处理器调试开发工具提供了很好的补充,参与到了建设国产处理器生态圈、提高处理器自主可控水平的进程中。