User:Demindiro/SBI
This page or section is a stub. You can help the wiki by accurately contributing to it. |
This page or section is a work in progress and may thus be incomplete. Its content may be changed in the near future. |
The RISC-V SBI (Supervisor Binary Interface) defines a common interface for RISC-V platforms for OSes. It hides platform-specific implementation details such that OSes are more portable.
Notably, it adds methods to facilitate IPI (Inter-Processor Interrupts).
The reference implementation is OpenSBI.
OpenSBI on QEMU
To run OpenSBI on QEMU, download the source and compile with make PLATFORM=generic CROSS_COMPILE=riscv64-your-os-
. Then add -bios path/to/opensbi/build/platform/generic/firmware/fw_jump.bin
fw_jump vs fw_payload vs fw_dynamic
fw_jump
should be used in conjunction with QEMU's-kernel
option
fw_payload
should directly include the kernel binary.
fw_dynamic
should be used if you use another bootloader that passes more information to OpenSBI.
Interface
The calling convention is the RISC-V ELF psABI. This means you'll need to save caller-saved registers!
The main difference is that the EID (Extension ID) goes into a7
and FID (Function ID) into a6
.
Extensions
Avoid the legacy extensions (EID 0x00 - 0xFF) as those are deprecated.
Timer (0x54494D45)
The timer extension has a single function sbi_set_timer
with FID 0x00. It takes a single uint64_t
argument.
To reset the timer, pass UINT64_MAX
. This clears the STIP
bit and effectively disables the timer.
QEMU as of 6.1.0-rc3 does not handle 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 = MIN(next, INT64_MAX); timer_mod(cpu->env.timer, next); } |