为什么调试qemu上运行的裸机程序时,gdb不显示所有的RISC-V csr ?



最近我正在学习RISC-V AIA架构,我需要做一些测试来验证我在AIA SPEC中发现的奇怪点。由于QEMU是唯一支持RISC-V AIA arch的硬件模拟器(也许这并不准确)(据我所知),我试图在QEMU上运行一些裸机程序在系统模式下,我的QEMU启动参数如下:

qemu-system-riscv64 -cpu rv64,h=true -nographic -M virt,aia=aplic-imsic -m 512M -bios none -kernel ${test_name}.elf -s -S

程序正常运行。但是,当我使用i all-r检查一些H-extension csr的状态时,我没有发现任何内容:

zero           0x0      0
ra             0x0      0x0
sp             0x0      0x0
gp             0x0      0x0
tp             0x0      0x0
t0             0x0      0
t1             0x0      0
t2             0x0      0
fp             0x0      0x0
s1             0x0      0
a0             0x0      0
a1             0x0      0
a2             0x0      0
a3             0x0      0
a4             0x0      0
a5             0x0      0
a6             0x0      0
a7             0x0      0
s2             0x0      0
s3             0x0      0
s4             0x0      0
s5             0x0      0
s6             0x0      0
s7             0x0      0
s8             0x0      0
s9             0x0      0
s10            0x0      0
s11            0x0      0
t3             0x0      0
t4             0x0      0
t5             0x0      0
t6             0x0      0
pc             0x1000   0x1000
ft0            {float = 0, double = 0}  (raw 0x0000000000000000)
ft1            {float = 0, double = 0}  (raw 0x0000000000000000)
ft2            {float = 0, double = 0}  (raw 0x0000000000000000)
ft3            {float = 0, double = 0}  (raw 0x0000000000000000)
ft4            {float = 0, double = 0}  (raw 0x0000000000000000)
ft5            {float = 0, double = 0}  (raw 0x0000000000000000)
ft6            {float = 0, double = 0}  (raw 0x0000000000000000)
ft7            {float = 0, double = 0}  (raw 0x0000000000000000)
fs0            {float = 0, double = 0}  (raw 0x0000000000000000)
fs1            {float = 0, double = 0}  (raw 0x0000000000000000)
fa0            {float = 0, double = 0}  (raw 0x0000000000000000)
fa1            {float = 0, double = 0}  (raw 0x0000000000000000)
fa2            {float = 0, double = 0}  (raw 0x0000000000000000)
--Type <RET> for more, q to quit, c to continue without paging--
fa3            {float = 0, double = 0}  (raw 0x0000000000000000)
fa4            {float = 0, double = 0}  (raw 0x0000000000000000)
fa5            {float = 0, double = 0}  (raw 0x0000000000000000)
fa6            {float = 0, double = 0}  (raw 0x0000000000000000)
fa7            {float = 0, double = 0}  (raw 0x0000000000000000)
fs2            {float = 0, double = 0}  (raw 0x0000000000000000)
fs3            {float = 0, double = 0}  (raw 0x0000000000000000)
fs4            {float = 0, double = 0}  (raw 0x0000000000000000)
fs5            {float = 0, double = 0}  (raw 0x0000000000000000)
fs6            {float = 0, double = 0}  (raw 0x0000000000000000)
fs7            {float = 0, double = 0}  (raw 0x0000000000000000)
fs8            {float = 0, double = 0}  (raw 0x0000000000000000)
fs9            {float = 0, double = 0}  (raw 0x0000000000000000)
fs10           {float = 0, double = 0}  (raw 0x0000000000000000)
fs11           {float = 0, double = 0}  (raw 0x0000000000000000)
ft8            {float = 0, double = 0}  (raw 0x0000000000000000)
ft9            {float = 0, double = 0}  (raw 0x0000000000000000)
ft10           {float = 0, double = 0}  (raw 0x0000000000000000)
ft11           {float = 0, double = 0}  (raw 0x0000000000000000)
fflags         0x0      RD:0 NV:0 DZ:0 OF:0 UF:0 NX:0
frm            0x0      FRM:0 [RNE (round to nearest; ties to even)]
fcsr           0x0      RD:0 NV:0 DZ:0 OF:0 UF:0 NX:0 FRM:0 [RNE (round to nearest; ties to even)]
sstatus        0x200000000      8589934592
sie            0x0      0
stvec          0x0      0
scounteren     0x0      0
sscratch       0x0      0
sepc           0x0      0
scause         0x0      0
stval          0x0      0
sip            0x0      0
satp           0x0      0
mstatus        0xa00000000      SD:0 VM:00 MXR:0 PUM:0 MPRV:0 XS:0 FS:0 MPP:0 HPP:0 SPP:0 MPIE:0 HPIE:0 SPIE:0 UPIE:0 MIE:0 HIE:0 SIE:0 UIE:0
misa           0x80000000001411ad       RV64ACDFHIMSU
medeleg        0x0      0
mideleg        0x0      0
mie            0x0      0
mtvec          0x0      0
mcounteren     0x0      0
mhpmevent3     0x0      0
mhpmevent4     0x0      0
mhpmevent5     0x0      0
mhpmevent6     0x0      0
mhpmevent7     0x0      0
mhpmevent8     0x0      0
mhpmevent9     0x0      0
--Type <RET> for more, q to quit, c to continue without paging--
mhpmevent10    0x0      0
mhpmevent11    0x0      0
mhpmevent12    0x0      0
mhpmevent13    0x0      0
mhpmevent14    0x0      0
mhpmevent15    0x0      0
mhpmevent16    0x0      0
mhpmevent17    0x0      0
mhpmevent18    0x0      0
mhpmevent19    0x0      0
mhpmevent20    0x0      0
mhpmevent21    0x0      0
mhpmevent22    0x0      0
mhpmevent23    0x0      0
mhpmevent24    0x0      0
mhpmevent25    0x0      0
mhpmevent26    0x0      0
mhpmevent27    0x0      0
mhpmevent28    0x0      0
mhpmevent29    0x0      0
mhpmevent30    0x0      0
mhpmevent31    0x0      0
mscratch       0x0      0
mepc           0x0      0
mcause         0x0      0
mtval          0x0      0
mip            0x80     128
pmpcfg0        0x0      0
pmpcfg1        Could not fetch register "pmpcfg1"; remote failure reply 'E14'
pmpcfg2        0x0      0
pmpcfg3        Could not fetch register "pmpcfg3"; remote failure reply 'E14'
pmpaddr0       0x0      0
pmpaddr1       0x0      0
pmpaddr2       0x0      0
pmpaddr3       0x0      0
pmpaddr4       0x0      0
pmpaddr5       0x0      0
pmpaddr6       0x0      0
pmpaddr7       0x0      0
pmpaddr8       0x0      0
pmpaddr9       0x0      0
pmpaddr10      0x0      0
pmpaddr11      0x0      0
pmpaddr12      0x0      0
pmpaddr13      0x0      0
pmpaddr14      0x0      0
--Type <RET> for more, q to quit, c to continue without paging--
pmpaddr15      0x0      0
tselect        0x0      0
tdata1         0x2000000000000000       2305843009213693952
tdata2         0x0      0
tdata3         Could not fetch register "tdata3"; remote failure reply 'E14'
mcycle         0x7bfd8d01bf1f6  2181262762308086
minstret       0x7bfd8d020bee2  2181262762622690
mhpmcounter3   0x0      0
mhpmcounter4   0x0      0
mhpmcounter5   0x0      0
mhpmcounter6   0x0      0
mhpmcounter7   0x0      0
mhpmcounter8   0x0      0
mhpmcounter9   0x0      0
mhpmcounter10  0x0      0
mhpmcounter11  0x0      0
mhpmcounter12  0x0      0
mhpmcounter13  0x0      0
mhpmcounter14  0x0      0
mhpmcounter15  0x0      0
mhpmcounter16  0x0      0
mhpmcounter17  0x0      0
mhpmcounter18  0x0      0
mhpmcounter19  0x0      0
mhpmcounter20  0x0      0
mhpmcounter21  0x0      0
mhpmcounter22  0x0      0
mhpmcounter23  0x0      0
mhpmcounter24  0x0      0
mhpmcounter25  0x0      0
mhpmcounter26  0x0      0
mhpmcounter27  0x0      0
mhpmcounter28  0x0      0
mhpmcounter29  0x0      0
mhpmcounter30  0x0      0
mhpmcounter31  0x0      0
cycle          0x7bfd8d0ba61a4  2181262772691364
time           0x0      0
instret        0x7bfd8d0caa32e  2181262773756718
hpmcounter3    0x0      0
hpmcounter4    0x0      0
hpmcounter5    0x0      0
hpmcounter6    0x0      0
hpmcounter7    0x0      0
hpmcounter8    0x0      0
hpmcounter9    0x0      0
--Type <RET> for more, q to quit, c to continue without paging--
hpmcounter10   0x0      0
hpmcounter11   0x0      0
hpmcounter12   0x0      0
hpmcounter13   0x0      0
hpmcounter14   0x0      0
hpmcounter15   0x0      0
hpmcounter16   0x0      0
hpmcounter17   0x0      0
hpmcounter18   0x0      0
hpmcounter19   0x0      0
hpmcounter20   0x0      0
hpmcounter21   0x0      0
hpmcounter22   0x0      0
hpmcounter23   0x0      0
hpmcounter24   0x0      0
hpmcounter25   0x0      0
hpmcounter26   0x0      0
hpmcounter27   0x0      0
hpmcounter28   0x0      0
hpmcounter29   0x0      0
hpmcounter30   0x0      0
hpmcounter31   0x0      0
mvendorid      0x0      0
marchid        0x70032  458802
mimpid         0x70032  458802
mhartid        0x0      0
priv           0x3      prv:3 [Machine]
senvcfg        0x0      0
menvcfg        0x0      0
mconfigptr     0x0      0

您可以看到,我使用-cpu,h=true选项来确保在这个RISC-V系统中支持h-extension,并且的值misa也可以证明这一点。我很好奇为什么我看不到任何一个H csr ?我的gdb版本是10.1(riscv64-unknown-elf-gdb riscv64-unknown-linux-gnu-gdb)。它是7.0.5Qemu。你能帮我解决这个问题吗?非常感谢。

GDB将显示的csr集由目标控制,因此在本例中是QEMU。目标将XML描述传递给GDB,该描述描述可用寄存器集。

连接到QEMU后,然后,从GDB提示符中,您可以要求GDB使用maintenance print xml-tdesc打印目标描述,这将打印QEMU发送的XML文档。此外,您可以执行maintenance print xml-tdesc FILENAME将文档写入FILENAME

您应该仔细检查这个XML文件,以确保您期望的寄存器不存在。我猜他们会失踪的。如果它们在该文件中,那么这是一个GDB问题。如果寄存器是而不是,那么问题是QEMU没有告诉GDB有关寄存器的信息。

因此,QEMU从这个表中构建它告诉GDB的csr集:

https://gitlab.com/qemu-project/qemu/-/blob/master/target/riscv/csr.c L3333

你应该检查表中是否有你想要的寄存器。如果寄存器不在那个表中,那么QEMU根本不知道寄存器。如果寄存器在那个表中,那么QEMU确实知道它们,但由于某种原因决定不告诉GDB。

将csr表转换为GDB的XML描述的代码可以在这里找到:

https://gitlab.com/qemu-project/qemu/-/blob/master/target/riscv/gdbstub.c L318

你会注意到有一些代码决定是否应该包含CSR:

predicate = csr_ops[i].predicate;
if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
/* Add CSR to XML document.  */
}

我不知道QEMU在这个最顶层之外,所以我真的不知道谓词检查是做什么的。

最新更新