[kvm-unit-tests PATCH v11 4/8] lib: riscv: Add functions for version checking

Clément Léger cleger at rivosinc.com
Thu Mar 20 01:08:45 PDT 2025



On 19/03/2025 18:31, Andrew Jones wrote:
> On Mon, Mar 17, 2025 at 05:46:49PM +0100, Clément Léger wrote:
>> Version checking was done using some custom hardcoded values, backport a
>> few SBI function and defines from Linux to do that cleanly.
>>
>> Signed-off-by: Clément Léger <cleger at rivosinc.com>
>> ---
>>  lib/riscv/asm/sbi.h | 15 +++++++++++++++
>>  lib/riscv/sbi.c     |  9 +++++++--
>>  2 files changed, 22 insertions(+), 2 deletions(-)
>>
>> diff --git a/lib/riscv/asm/sbi.h b/lib/riscv/asm/sbi.h
>> index 2f4d91ef..ee9d6e50 100644
>> --- a/lib/riscv/asm/sbi.h
>> +++ b/lib/riscv/asm/sbi.h
>> @@ -18,6 +18,13 @@
>>  #define SBI_ERR_IO			-13
>>  #define SBI_ERR_DENIED_LOCKED		-14
>>  
>> +/* SBI spec version fields */
>> +#define SBI_SPEC_VERSION_MAJOR_SHIFT	24
>> +#define SBI_SPEC_VERSION_MAJOR_MASK	0x7f
>> +#define SBI_SPEC_VERSION_MINOR_MASK	0xffffff
>> +#define SBI_SPEC_VERSION_MASK		((SBI_SPEC_VERSION_MAJOR_MASK << SBI_SPEC_VERSION_MAJOR_SHIFT) | \
>> +					SBI_SPEC_VERSION_MINOR_MASK)
>                                        ^ needs one more space
>> +
>>  #ifndef __ASSEMBLER__
>>  #include <cpumask.h>
>>  
>> @@ -110,6 +117,13 @@ struct sbiret {
>>  	long value;
>>  };
>>  
>> +/* Make SBI version */
> 
> Unnecessary comment, it's the same as the function name.

Yeah that's a copy/paste from Linux, didn't cleanup.

> 
>> +static inline unsigned long sbi_mk_version(unsigned long major, unsigned long minor)
>> +{
>> +	return ((major & SBI_SPEC_VERSION_MAJOR_MASK) << SBI_SPEC_VERSION_MAJOR_SHIFT)
>> +		| (minor & SBI_SPEC_VERSION_MINOR_MASK);
>> +}
>> +
>>  struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
>>  			unsigned long arg1, unsigned long arg2,
>>  			unsigned long arg3, unsigned long arg4,
>> @@ -124,6 +138,7 @@ struct sbiret sbi_send_ipi_cpu(int cpu);
>>  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);
>>  long sbi_probe(int ext);
>>  
>>  #endif /* !__ASSEMBLER__ */
>> diff --git a/lib/riscv/sbi.c b/lib/riscv/sbi.c
>> index 02dd338c..9d4eb541 100644
>> --- a/lib/riscv/sbi.c
>> +++ b/lib/riscv/sbi.c
>> @@ -107,12 +107,17 @@ 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_spec_version(void)
>> +{
>> +	return sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_GET_SPEC_VERSION, 0, 0, 0, 0, 0, 0);
>> +}
>> +
>>  long sbi_probe(int ext)
>>  {
>>  	struct sbiret ret;
>>  
>> -	ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_GET_SPEC_VERSION, 0, 0, 0, 0, 0, 0);
>> -	assert(!ret.error && (ret.value & 0x7ffffffful) >= 2);
>> +	ret = sbi_get_spec_version();
>> +	assert(!ret.error && (ret.value & SBI_SPEC_VERSION_MASK) >= sbi_mk_version(0, 2));
>>  
>>  	ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, ext, 0, 0, 0, 0, 0);
>>  	assert(!ret.error);
>> -- 
>> 2.47.2
>>
> 
> I fixed those two things up while applying.

Thanks Andrew,

Clément

> 
> Thanks,
> drew




More information about the kvm-riscv mailing list