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@xxxxxxxxxxxx> > --- > 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 >