handengke
handengke

Reputation: 1

Why does gdb do not show all RISC-V CSRs when debugging bare-metal program running on qemu?

Recently I'm learning about RISC-V AIA architecture and I need to do some test to verify the curious points that I found in AIA SPEC. Since QEMU is the only hardware simulator (maybe this is not accurate)supporting the RISC-V AIA arch(as far as I know), I've tried to run some bare-metal programs on Qemu in system mode, my start param for Qemu is as below:

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

The program runs as normal. However, when I use i all-r to check the status of some H-extension CSRs, I found nothing:

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

As you can see, I use the -cpu,h=true option to make sure that h-extension is supported in this RISC-V system, and the value of misa can also prove this. I'm curious about why cannot I see any one of H CSRs? My gdb version is 10.1(riscv64-unknown-elf-gdb,riscv64-unknown-linux-gnu-gdb).And it's 7.0.5 for Qemu. Could you please help me to solve this problem? Thank you so much.

Upvotes: 0

Views: 2541

Answers (1)

Andrew
Andrew

Reputation: 4771

The set of CSRs that GDB will display is controlled by the target, so QEMU in this case. The target passes an XML description to GDB that describes the set of available registers.

After connecting to QEMU, then, from the GDB prompt, you can ask GDB to print the target description using maintenance print xml-tdesc, this will print the XML document that the QEMU sent. Additionally you can do maintenance print xml-tdesc FILENAME to write the document out to FILENAME.

You should double check this XML file to ensure the registers you expect are not present. My guess is they will be missing. If they are in that file then this is a GDB issue. If the registers are not in that file then the problem is QEMU not telling GDB about the registers.

So QEMU builds the set of CSRs it tells GDB about from this table:

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

You should check that table for the registers you are expecting. If the registers are not in that table, then QEMU doesn't know about the registers at all. If the registers are in that table then QEMU does know about them, but has decided not to tell GDB for some reason.

The code that converts the table of CSRs into the XML description for GDB can be found here:

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

You'll notice there is some code that decides if a CSR should be included or not:

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

I don't know QEMU beyond this very top level, so I don't really know what that predicate check is doing.

Upvotes: 1

Related Questions