Skip to content

Writing the 'stimecmp' of the SSTC extension in gdb mode will result in illegal calculation

When I was running linux in gdb mode with qemu-system-riscv32, I found that writing the csr stimecmp would cause a 'Floating point exception (core dumped)'.

The function call stack is as follows:

#0  0x0000555555e077ac in __divti3 ()
#1  0x0000555555ac1801 in muldiv64 (c=0, b=1000000000, a=326)
    at /Local/home/liuxu/work/qemu/qemu/include/qemu/host-utils.h:56
#2  riscv_timer_write_timecmp
    (env=0x7ffff6aec850, timer=0x5555568500b0, timecmp=<optimized out>, delta=delta@entry=0, timer_irq=timer_irq@entry=32) at ../target/riscv/time_helper.c:103
#3  0x0000555555ae05f2 in write_stimecmp
    (csrno=<optimized out>, val=<optimized out>, env=<optimized out>)
    at ../target/riscv/csr.c:1138
#4  write_stimecmp (env=<optimized out>, csrno=<optimized out>, val=<optimized out>)
    at ../target/riscv/csr.c:1122
#5  0x0000555555add56d in riscv_csrrw_do64
    (env=env@entry=0x7ffff6aec850, csrno=<optimized out>, ret_value=ret_value@entry=0x0, new_value=813304, write_mask=write_mask@entry=4294967295) at ../target/riscv/csr.c:4601
#6  0x0000555555ae1472 in riscv_csrrw
    (env=env@entry=0x7ffff6aec850, csrno=<optimized out>, ret_value=ret_value@entry=0x0, new_value=<optimized out>, write_mask=write_mask@entry=4294967295) at ../target/riscv/csr.c:4625
#7  0x0000555555ae4687 in helper_csrw
    (env=0x7ffff6aec850, csr=<optimized out>, src=<optimized out>)

Tracing the source code of qemu reveals that the problem lies in ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq) of riscv_timer_write_timecmp. In gdb mode, the frequency of the timer is set to 0, corresponding to the parameter c of muldiv64, which leads to an illegal operation of dividing by 0. However, running linux directly with qemu-system-riscv32 is normal.

I wonder if this is a design flaw or if there is a way to avoid it in gdb mode.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information