用龙芯EJTAG硬件断点优化Linux ptrace watch性能
·
hev
在MIPS标准的协处理器0(CP0)中定义一组硬件watchpoints接口,由于某些原因,龙芯3系列处理器并未实现,这就导致了在该架构Linux系统中用gdb watch只能使用软件断点,真心非常、非常慢。:(
好消息是龙芯3系列处理器是实现了MIPS EJTAG的,兼容2.61标准,那么能否利用MIPS EJTAG的硬件断点功能部件实现Linux ptrace的watchpoints功能呢?答案是肯定的。让我们一起看看具体的方法吧。
首先,我们需要更改BIOS中的异常处理函数,将EJTAG调试异常重新路由至Linux内核中处理,因为MIPS EJTAG异常处理程序的入口地址固定为0xbfc00480,在不能修改BIOS的情况下,可以使用龙芯L1X地址路由窗口将0x1fc00400/1K路由至RAM。
/* Debug exception */
.align 7 /* bfc00480 */
.set push
.set noreorder
.set arch=mips64r2
dmtc0 k0, CP0_DESAVE
mfc0 k0, CP0_DEBUG
andi k0, 0x2
beqz k0, 1f
mfc0 k0, CP0_STATUS
andi k0, 0x18
bnez k0, 2f
nop
1:
mfc0 k0, CP0_EBASE
ins k0, zero, 0, 12
addiu k0, 0x480
jr k0
dmfc0 k0, CP0_DESAVE
2:
li k0, 0xdeadbeef
dmtc0 k0, CP0_DEPC
dmfc0 k0, CP0_DESAVE
sync
deret
.set pop
这段处理程序实现了两个功能:
- 将来自用户态的sdbbp指令触发的异常路由至地址 0xdeadbeef。
- 将来自内核态的sdbbp指令触发的异常或是任意态的非sdbbp触发的异常路由至 ebase+0x480。
接着,我们还需要修改内核,实现下列功能:
- 实现 EJTAG watch 相关的 probe、install、read、clear 等操作,及合适的调试异常处理程序。
- 实现 Linux ptrace watch 接口与 EJTAG watch 的对接。