[kvm-unit-tests PATCH v10 5/8] lib: riscv: add functions to get implementer ID and version
Andrew Jones
ajones at ventanamicro.com
Mon Mar 17 05:46:03 PDT 2025
On Mon, Mar 17, 2025 at 11:19:51AM +0100, Clément Léger wrote:
> These function will be used by SSE tests to check for a specific opensbi
> version. sbi_impl_check() is an helper allowing to check for a specific
> SBI implementor without needing to check for ret.error.
>
> Signed-off-by: Clément Léger <cleger at rivosinc.com>
> ---
> lib/riscv/asm/sbi.h | 30 ++++++++++++++++++++++++++++++
> lib/riscv/sbi.c | 10 ++++++++++
> 2 files changed, 40 insertions(+)
>
> diff --git a/lib/riscv/asm/sbi.h b/lib/riscv/asm/sbi.h
> index 197288c7..06bcec16 100644
> --- a/lib/riscv/asm/sbi.h
> +++ b/lib/riscv/asm/sbi.h
> @@ -18,6 +18,19 @@
> #define SBI_ERR_IO -13
> #define SBI_ERR_DENIED_LOCKED -14
>
> +#define SBI_IMPL_BBL 0
> +#define SBI_IMPL_OPENSBI 1
> +#define SBI_IMPL_XVISOR 2
> +#define SBI_IMPL_KVM 3
> +#define SBI_IMPL_RUSTSBI 4
> +#define SBI_IMPL_DIOSIX 5
> +#define SBI_IMPL_COFFER 6
> +#define SBI_IMPL_XEN Project 7
s/Project//
> +#define SBI_IMPL_POLARFIRE_HSS 8
> +#define SBI_IMPL_COREBOOT 9
> +#define SBI_IMPL_OREBOOT 10
> +#define SBI_IMPL_BHYVE 11
> +
> /* SBI spec version fields */
> #define SBI_SPEC_VERSION_DEFAULT 0x1
> #define SBI_SPEC_VERSION_MAJOR_SHIFT 24
> @@ -123,6 +136,10 @@ static inline unsigned long sbi_mk_version(unsigned long major, unsigned long mi
> | (minor & SBI_SPEC_VERSION_MINOR_MASK);
> }
>
> +static inline unsigned long sbi_impl_opensbi_mk_version(unsigned long major, unsigned long minor)
> +{
> + return ((major << 16) | (minor));
Should at least mask minor, best to mask both.
> +}
>
> struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
> unsigned long arg1, unsigned long arg2,
> @@ -139,7 +156,20 @@ struct sbiret sbi_send_ipi_cpumask(const cpumask_t *mask);
> struct sbiret sbi_send_ipi_broadcast(void);
> struct sbiret sbi_set_timer(unsigned long stime_value);
> struct sbiret sbi_get_spec_version(void);
> +struct sbiret sbi_get_imp_version(void);
> +struct sbiret sbi_get_imp_id(void);
> long sbi_probe(int ext);
>
> +static inline bool sbi_check_impl(unsigned long impl)
> +{
> + struct sbiret ret;
> +
> + ret = sbi_get_imp_id();
> + if (ret.error)
> + return false;
> +
> + return ret.value == impl;
Or, more tersely,
struct sbiret ret = sbi_get_imp_id();
return !ret.error && ret.value == impl;
but an assert would make more sense, since get-impl-id really shouldn't
fail, unless the SBI version is 0.1, which we don't support.
> +}
> +
> #endif /* !__ASSEMBLER__ */
> #endif /* _ASMRISCV_SBI_H_ */
> diff --git a/lib/riscv/sbi.c b/lib/riscv/sbi.c
> index 3c395cff..9cb5757e 100644
> --- a/lib/riscv/sbi.c
> +++ b/lib/riscv/sbi.c
> @@ -107,6 +107,16 @@ struct sbiret sbi_set_timer(unsigned long stime_value)
> return sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, 0, 0, 0, 0, 0);
> }
>
> +struct sbiret sbi_get_imp_version(void)
> +{
> + return sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_VERSION, 0, 0, 0, 0, 0, 0);
> +}
> +
> +struct sbiret sbi_get_imp_id(void)
> +{
> + return sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_GET_IMP_ID, 0, 0, 0, 0, 0, 0);
> +}
Going with error asserts, then we can just put the asserts in these
functions and return ret.value directly, like sbi_probe() does, which
means sbi_check_impl() can be dropped.
Thanks,
drew
> +
> struct sbiret sbi_get_spec_version(void)
> {
> return sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_GET_SPEC_VERSION, 0, 0, 0, 0, 0, 0);
> --
> 2.47.2
>
More information about the kvm-riscv
mailing list