Rocketchip RISC-V Debug调试硬件相关(四)hartIsInReset

本文对riscv的hart-reset功能和halt-on-reset功能进行说明,并详细说明该功能实现的方式和顶层信号hartIsInReset信号的处理方式。阅读第一篇文章,了解riscv debug模块的大概时钟域和复位划分。

Rocketchip RISC-V Debug调试硬件相关(一)_远古架构师alanwu的博客-CSDN博客icon-default.png?t=M666https://blog.csdn.net/heyuming20062007/article/details/125594822?spm=1001.2014.3001.5501

一、hartIsInReset/halt-on-reset

hart-reset and halt-on-reset functions have been changed to simple I/O and require customer logic involvement. The two signals are grouped in a new ResetCtrlIO bundle. hartIsInReset is a logical equivalent of core_reset and is synchronous to core_clock. For debug module halt-on-reset function, this signal must remain asserted for at least 4 debug_clock cycles for the DM to assert debug interrupt plus 3 core_clock cycles for the debug interrupt to reach the core prior to the core_reset signal being deasserted. Halt-on-reset will not work if either clock or core_clock is not running.

从官方文档的解释说明上可以得知,该信号从逻辑上等同于core复位,也就是说在core复位期间,要将该信号拉高。同时,对拉高的时间周期数也有要求,必须拉高4 debug clock + 3 core clock。其中前4个debug clock用于将该拉高信号转变成debug中断传递给内核hart,具体原因后续分析,后3个core clock用于内核hart对该debug中断的响应,内核会响应中断进入0x800位置,等待调试命令介入。

该功能就是halt-on-reset的调试功能的具体实现,也就是说当core复位拉高时,debug中断就会有效拉高并传递到hart,等core复位释放后,hart会在第一时间响应该中断拉高并进入0x800循环等待调试命令。

这里分析下为什么需要4个debug clock,通过对hartIsInReset内部逻辑的分析,该信号主要用在了下图所示的三个位置,这里分别对这三个位置进行说明并提供一种SoC集成的方式。

二、debug interrupt

下图是一个双核rocketchip的RTL电路实现,可以看到haltIsInReset信号经过内部异步处理后,送给了dmInner,dmInner内部逻辑处理后通过io_debug_int信号输出,该中断受Int Mask中断屏蔽位控制,如果不需要打开和关闭该中断功能。

需要注意的是,该中断由于经过了dmInner,且受flop寄存器控制,因此在core复位有效时,dmInner必须处于工作状态,如果dmInner和core同时复位,会导致halt on reset功能失效!

设计人员比较关心的是这个中断屏蔽受谁控制,具体可以看下图。dmInner的io_debug_int中断,会先送到dmOuter内部, 和dmcontrol寄存器的haltreq、resumreq组成一对作为debug中断送给hart内核。

中断屏蔽和清除通过dmcontrol寄存器的setresethaltreq和clrresethaltreq来完成,且每个核的hartIsInReset的中断屏蔽都可以单独配置。

三、HaveResetBitRegs

halt-on-reset原理搞清楚以后,还需要理解上位机怎么配合完成上述动作,这就涉及到另一条通路的处理了,如下图所示:

这条通路的电路逻辑较为复杂,但主要是影响了三个寄存器的数值,其中寄存器ResumReqRegs较为特殊,该寄存器影响debug中断响应后的调试模式退出。当core复位释放后,如果屏蔽不使能,内核会停在第一条有效指令前等待调试命令,此时内核会响应debug中断,并固定跳转到0x800的park loop位置。该位置为内核固定跳转,且该位置的程序为固定内容,无法修改。通过对该部分的机器码研究,该部分的反汇编内容如下:

也就是说park loop一直在等0x401用户自定义的CSR寄存器变为2,这个寄存器实际上就是ResumReqRegs。

四、调试程序

调试程序可以使用dmcontrol寄存器的ndmreset来控制内核复位,当内核处于复位状态时,可以先打开halt-on-reset的中断屏蔽位,然后释放ndmreset让内核立即进入debug模式。如果是外部复位,例如硬复位导致core复位有效,上位机也可以通过查询dmstatus寄存器的allhavereset、anyhavereset位来判断内核复位是否完成。每个核的halt-on-reset可以单独控制,通过dmcontrol寄存器的hartsello和Hart Array Mask寄存器完成。

五、总结

使用halt-on-reset功能,必须保证dmInner在core复位时保持工作状态,这就要求dmInner的复位不能和core复位一致。另外,顶层的hartIsInReset信号不能tie 1处理,会导致debug中断响应后无法跳出,无法跳出的原因是resumeReqRegs寄存器的值不能通过resumreq请求改成2。

猜你喜欢

转载自blog.csdn.net/heyuming20062007/article/details/126059860