Message ID | 20250317101956.526834-6-cleger@rivosinc.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | riscv: add SBI SSE extension tests | expand |
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@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 >
On 17/03/2025 13:46, Andrew Jones wrote: > 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@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. Ack, I'll modify that. Thanks, Clément > > 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 >>
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 +#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)); +} 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; +} + #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); +} + 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);
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@rivosinc.com> --- lib/riscv/asm/sbi.h | 30 ++++++++++++++++++++++++++++++ lib/riscv/sbi.c | 10 ++++++++++ 2 files changed, 40 insertions(+)