User:Demindiro/SBI: Difference between revisions

Important note about QEMU being buggy
m (Add to RISC-V category)
(Important note about QEMU being buggy)
Line 38:
The timer extension has a single function <code>sbi_set_timer</code> with FID 0x00. It takes a single <code>uint64_t</code> argument.
 
To reset the timer, pass <code>UINT64_MAX</code>. This clears the <code>STIP</code> bit and effectively disables the timer.
Before calling it, ensure that STIE is cleared! Otherwise you may get sporadic interrupts. i.e:
 
<source lang="asm">
li s0, 1 << 5
csrc sie, s0
li a7, 0x54494d45
li a6, 0
ecall
csrs sie, s0
</source>
 
{{NoteBox
| <p>QEMU as of 6.1.0-rc3 [https://gitlab.com/qemu-project/qemu/-/issues/493 does not handle <code>UINT64_MAX</code> properly]. To fix this, apply the following patch:</p>
<pre style="text-align:left">
diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c
index 0f41e5ea1c..e65e71e5ec 100644
--- a/hw/intc/sifive_clint.c
+++ b/hw/intc/sifive_clint.c
@@ -61,6 +61,8 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
/* back to ns (note args switched in muldiv64) */
next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
+ /* ensure next does not overflow, as timer_mod takes a signed value */
+ next = MAX(next, INT64_MAX);
timer_mod(cpu->env.timer, next);
}
</pre>
}}
 
== See Also ==
Anonymous user