[RFC PATCH 4/6] xen/riscv: Add sbi.c, sbi.h

Xie Xun posted 6 patches 3 years, 6 months ago
[RFC PATCH 4/6] xen/riscv: Add sbi.c, sbi.h
Posted by Xie Xun 3 years, 6 months ago
Signed-off-by: Xie Xun <xiexun162534@gmail.com>
---
 xen/arch/riscv/Makefile          |   1 +
 xen/arch/riscv/include/asm/sbi.h | 275 ++++++++++++++++++
 xen/arch/riscv/sbi.c             | 483 +++++++++++++++++++++++++++++++
 3 files changed, 759 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/sbi.h
 create mode 100644 xen/arch/riscv/sbi.c

diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index 3a57556631..c61349818f 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -8,6 +8,7 @@ obj-y   += irq.o
 obj-y   += p2m.o
 obj-y   += mm.o
 obj-y   += percpu.o
+obj-y   += sbi.o
 obj-y   += setup.o
 obj-y   += shutdown.o
 obj-y   += smp.o
diff --git a/xen/arch/riscv/include/asm/sbi.h b/xen/arch/riscv/include/asm/sbi.h
new file mode 100644
index 0000000000..eb727f1a5e
--- /dev/null
+++ b/xen/arch/riscv/include/asm/sbi.h
@@ -0,0 +1,275 @@
+/**
+ * Copyright (c) 2021 Vates SAS.
+ *
+ * Taken from xvisor, modified by Bobby Eshleman (bobby.eshleman@gmail.com).
+ *
+ * Taken/modified from Xvisor project with the following copyright:
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __CPU_SBI_H__
+#define __CPU_SBI_H__
+
+#include <xen/types.h>
+
+/* SBI Extension IDs */
+#define	SBI_EXT_0_1_SET_TIMER			0x0
+#define SBI_EXT_0_1_CONSOLE_PUTCHAR		0x1
+#define SBI_EXT_0_1_CONSOLE_GETCHAR		0x2
+#define SBI_EXT_0_1_CLEAR_IPI			0x3
+#define SBI_EXT_0_1_SEND_IPI			0x4
+#define SBI_EXT_0_1_REMOTE_FENCE_I		0x5
+#define SBI_EXT_0_1_REMOTE_SFENCE_VMA		0x6
+#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID	0x7
+#define SBI_EXT_0_1_SHUTDOWN			0x8
+#define SBI_EXT_BASE				0x10
+#define SBI_EXT_TIME				0x54494D45
+#define SBI_EXT_IPI				0x735049
+#define SBI_EXT_RFENCE				0x52464E43
+
+/* SBI function IDs for BASE extension */
+#define SBI_EXT_BASE_GET_SPEC_VERSION		0x0
+#define SBI_EXT_BASE_GET_IMP_ID			0x1
+#define	SBI_EXT_BASE_GET_IMP_VERSION		0x2
+#define	SBI_EXT_BASE_PROBE_EXT			0x3
+#define	SBI_EXT_BASE_GET_MVENDORID		0x4
+#define	SBI_EXT_BASE_GET_MARCHID		0x5
+#define	SBI_EXT_BASE_GET_MIMPID			0x6
+
+#define SBI_SPEC_VERSION_MAJOR_SHIFT		24
+#define SBI_SPEC_VERSION_MAJOR_MASK		0x7f
+#define SBI_SPEC_VERSION_MINOR_MASK		0xffffff
+
+/* SBI function IDs for TIME extension */
+#define SBI_EXT_TIME_SET_TIMER			0x0
+
+/* SBI function IDs for IPI extension */
+#define SBI_EXT_IPI_SEND_IPI			0x0
+
+/* SBI function IDs for RFENCE extension */
+#define	SBI_EXT_RFENCE_REMOTE_FENCE_I		0x0
+#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA	0x1
+#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID	0x2
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA	0x3
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID	0x4
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA	0x5
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID	0x6
+
+#define SBI_EXT_VENDOR_START			0x09000000
+#define SBI_EXT_VENDOR_END			0x09FFFFFF
+
+/* SBI return error codes */
+#define SBI_SUCCESS		0
+#define SBI_ERR_FAILURE		-1
+#define SBI_ERR_NOT_SUPPORTED	-2
+#define SBI_ERR_INVALID_PARAM   -3
+#define SBI_ERR_DENIED		-4
+#define SBI_ERR_INVALID_ADDRESS -5
+
+#define SBI_SPEC_VERSION_DEFAULT	0x1
+
+struct cpumask;
+
+struct sbiret {
+	long error;
+	long value;
+};
+
+struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
+			unsigned long arg1, unsigned long arg2,
+			unsigned long arg3, unsigned long arg4,
+			unsigned long arg5);
+
+/**
+ * Convert SBI spec error code into Xvisor error code
+ *
+ * @return errno error code
+ */
+int sbi_err_map_xvisor_errno(int err);
+
+/**
+ * Convert logical CPU mask to hardware HART mask
+ *
+ * @param cmask input logical CPU mask
+ * @param hmask output hardware HART mask
+ */
+void sbi_cpumask_to_hartmask(const struct cpumask *cmask,
+			     struct cpumask *hmask);
+
+/**
+ * Writes given character to the console device.
+ *
+ * @param ch The data to be written to the console.
+ */
+void sbi_console_putchar(int ch);
+
+/**
+ * Reads a character from console device.
+ *
+ * @return the character read from console
+ */
+int sbi_console_getchar(void);
+
+/**
+ * Remove all the harts from executing supervisor code.
+ */
+void sbi_shutdown(void);
+
+/**
+ * Clear any pending IPIs for the calling HART.
+ */
+void sbi_clear_ipi(void);
+
+/**
+ * Send IPIs to a set of target HARTs.
+ *
+ * @param hart_mask mask representing set of target HARTs
+ */
+void sbi_send_ipi(const unsigned long *hart_mask);
+
+/**
+ * Program the timer for next timer event.
+ *
+ * @param stime_value Timer value after which next timer event should fire.
+ */
+void sbi_set_timer(u64 stime_value);
+
+/**
+ * Send FENCE_I to a set of target HARTs.
+ *
+ * @param hart_mask mask representing set of target HARTs
+ */
+void sbi_remote_fence_i(const unsigned long *hart_mask);
+
+/**
+ * Send SFENCE_VMA to a set of target HARTs.
+ *
+ * @param hart_mask mask representing set of target HARTs
+ * @param start virtual address start
+ * @param size virtual address size
+ */
+void sbi_remote_sfence_vma(const unsigned long *hart_mask,
+			   unsigned long start,
+			   unsigned long size);
+
+/**
+ * Send SFENCE_VMA_ASID to a set of target HARTs.
+ *
+ * @param hart_mask mask representing set of target HARTs
+ * @param start virtual address start
+ * @param size virtual address size
+ * @param asid address space ID
+ */
+void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
+				unsigned long start,
+				unsigned long size,
+				unsigned long asid);
+
+/**
+ * Send HFENCE_GVMA to a set of target HARTs.
+ *
+ * @param hart_mask mask representing set of target HARTs
+ * @param start guest physical address start
+ * @param size guest physical address size
+ */
+void sbi_remote_hfence_gvma(const unsigned long *hart_mask,
+			    unsigned long start,
+			    unsigned long size);
+
+/**
+ * Send HFENCE_GVMA_VMID to a set of target HARTs.
+ *
+ * @param hart_mask mask representing set of target HARTs
+ * @param start guest physical address start
+ * @param size guest physical address size
+ * @param vmid virtual machine ID
+ */
+void sbi_remote_hfence_gvma_vmid(const unsigned long *hart_mask,
+				 unsigned long start,
+				 unsigned long size,
+				 unsigned long vmid);
+
+/**
+ * Send HFENCE_VVMA to a set of target HARTs.
+ *
+ * @param hart_mask mask representing set of target HARTs
+ * @param start virtual address start
+ * @param size virtual address size
+ */
+void sbi_remote_hfence_vvma(const unsigned long *hart_mask,
+			    unsigned long start,
+			    unsigned long size);
+
+/**
+ * Send HFENCE_VVMA_ASID to a set of target HARTs.
+ *
+ * @param hart_mask mask representing set of target HARTs
+ * @param start virtual address start
+ * @param size virtual address size
+ * @param asid address space ID
+ */
+void sbi_remote_hfence_vvma_asid(const unsigned long *hart_mask,
+				 unsigned long start,
+				 unsigned long size,
+				 unsigned long asid);
+
+/**
+ * Check given SBI extension is supported or not.
+ *
+ * @param ext extension ID
+ * @return >= 0 for supported AND -EOPNOTSUPP for not-supported
+ */
+int sbi_probe_extension(long ext);
+
+/**
+ * Check underlying SBI implementation is v0.1 only
+ *
+ * @return 1 for SBI v0.1 AND 0 for higer version
+ */
+int sbi_spec_is_0_1(void);
+
+/**
+ * Check underlying SBI implementation has v0.2 RFENCE
+ *
+ * @return 1 for supported AND 0 for not-supported
+ */
+int sbi_has_0_2_rfence(void);
+
+/**
+ * Get SBI spec major version
+ *
+ * @return major version number
+ */
+unsigned long sbi_major_version(void);
+
+/**
+ * Get SBI spec minor version
+ *
+ * @return minor version number
+ */
+unsigned long sbi_minor_version(void);
+
+/**
+ * Initialize SBI library
+ *
+ * @return 0 on success, otherwise negative errno on failure
+ */
+int sbi_init(void);
+
+#endif // __CPU_SBI_H__
diff --git a/xen/arch/riscv/sbi.c b/xen/arch/riscv/sbi.c
new file mode 100644
index 0000000000..be5f337a88
--- /dev/null
+++ b/xen/arch/riscv/sbi.c
@@ -0,0 +1,483 @@
+/**
+ * Taken and modified from the xvisor project with the copyright Copyright (c)
+ * 2019 Western Digital Corporation or its affiliates and author Anup Patel
+ * (anup.patel@wdc.com).
+ *
+ * Modified by Bobby Eshleman (bobby.eshleman@gmail.com).
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ * Copyright (c) 2021 Vates SAS.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <xen/errno.h>
+#include <xen/init.h>
+#include <xen/smp.h>
+
+#include <asm/system.h>
+#include <asm/sbi.h>
+
+static unsigned long sbi_spec_version = SBI_SPEC_VERSION_DEFAULT;
+
+struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
+			unsigned long arg1, unsigned long arg2,
+			unsigned long arg3, unsigned long arg4,
+			unsigned long arg5)
+{
+	struct sbiret ret;
+
+	register unsigned long a0 asm ("a0") = (unsigned long)(arg0);
+	register unsigned long a1 asm ("a1") = (unsigned long)(arg1);
+	register unsigned long a2 asm ("a2") = (unsigned long)(arg2);
+	register unsigned long a3 asm ("a3") = (unsigned long)(arg3);
+	register unsigned long a4 asm ("a4") = (unsigned long)(arg4);
+	register unsigned long a5 asm ("a5") = (unsigned long)(arg5);
+	register unsigned long a6 asm ("a6") = (unsigned long)(fid);
+	register unsigned long a7 asm ("a7") = (unsigned long)(ext);
+	asm volatile ("ecall"
+		      : "+r" (a0), "+r" (a1)
+		      : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
+		      : "memory");
+	ret.error = a0;
+	ret.value = a1;
+
+	return ret;
+}
+
+int sbi_err_map_xen_errno(int err)
+{
+	switch (err) {
+	case SBI_SUCCESS:
+		return 0;
+	case SBI_ERR_DENIED:
+		return -EACCES;
+	case SBI_ERR_INVALID_PARAM:
+		return -EINVAL;
+	case SBI_ERR_INVALID_ADDRESS:
+		return -EFAULT;
+	case SBI_ERR_NOT_SUPPORTED:
+	case SBI_ERR_FAILURE:
+	default:
+		return -EOPNOTSUPP;
+	};
+}
+
+void sbi_cpumask_to_hartmask(const struct cpumask *cmask,
+			     struct cpumask *hmask)
+{
+	u32 cpu;
+	unsigned long hart;
+
+	if (!cmask || !hmask)
+		return;
+
+	cpumask_clear(hmask);
+	for_each_cpu(cpu, cmask) {
+		if (CONFIG_NR_CPUS <= cpu) {
+			printk(XENLOG_ERR "SBI: invalid hart=%lu for cpu=%d\n",
+				     hart, cpu);
+			continue;
+		}
+        hart = pcpu_info[cpu].processor_id;
+		cpumask_set_cpu(hart, hmask);
+	}
+}
+
+void sbi_console_putchar(int ch)
+{
+	sbi_ecall(SBI_EXT_0_1_CONSOLE_PUTCHAR, 0, ch, 0, 0, 0, 0, 0);
+}
+
+int sbi_console_getchar(void)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_0_1_CONSOLE_GETCHAR, 0, 0, 0, 0, 0, 0, 0);
+
+	return ret.error;
+}
+
+void sbi_shutdown(void)
+{
+	sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0);
+}
+
+void sbi_clear_ipi(void)
+{
+	sbi_ecall(SBI_EXT_0_1_CLEAR_IPI, 0, 0, 0, 0, 0, 0, 0);
+}
+
+static int __sbi_send_ipi_v01(const unsigned long *hart_mask)
+{
+	sbi_ecall(SBI_EXT_0_1_SEND_IPI, 0,
+		  (unsigned long)hart_mask, 0, 0, 0, 0, 0);
+	return 0;
+}
+
+static void __sbi_set_timer_v01(u64 stime_value)
+{
+#ifdef CONFIG_RISCV_64
+	sbi_ecall(SBI_EXT_0_1_SET_TIMER, 0, stime_value, 0, 0, 0, 0, 0);
+#else
+	sbi_ecall(SBI_EXT_0_1_SET_TIMER, 0, stime_value,
+		  stime_value >> 32, 0, 0, 0, 0);
+#endif
+}
+
+static int __sbi_rfence_v01(unsigned long fid,
+			    const unsigned long *hart_mask,
+			    unsigned long start, unsigned long size,
+			    unsigned long arg4, unsigned long arg5)
+{
+	int result = 0;
+
+	switch (fid) {
+	case SBI_EXT_RFENCE_REMOTE_FENCE_I:
+		sbi_ecall(SBI_EXT_0_1_REMOTE_FENCE_I, 0,
+			  (unsigned long)hart_mask, 0, 0, 0, 0, 0);
+		break;
+	case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA:
+		sbi_ecall(SBI_EXT_0_1_REMOTE_SFENCE_VMA, 0,
+			  (unsigned long)hart_mask, start, size,
+			  0, 0, 0);
+		break;
+	case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID:
+		sbi_ecall(SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID, 0,
+			  (unsigned long)hart_mask, start, size,
+			  arg4, 0, 0);
+		break;
+	default:
+		printk("%s: unknown function ID [%lu]\n", __func__, fid);
+		result = -EINVAL;
+		break;
+	};
+
+	return result;
+}
+
+static void __sbi_set_timer_v02(u64 stime_value)
+{
+#ifdef CONFIG_RISCV_64
+	sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, 0,
+		  0, 0, 0, 0);
+#else
+	sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value,
+		  stime_value >> 32, 0, 0, 0, 0);
+#endif
+}
+
+static int __sbi_send_ipi_v02(const unsigned long *hart_mask)
+{
+	struct cpumask tmask;
+	unsigned long hart, hmask, hbase;
+	struct sbiret ret = {0};
+	int result;
+
+	if (!hart_mask) {
+		sbi_cpumask_to_hartmask(&cpu_online_map, &tmask);
+		hart_mask = cpumask_bits(&tmask);
+	}
+
+	hmask = hbase = 0;
+	for_each_set_bit(hart, hart_mask, CONFIG_NR_CPUS) {
+		if (hmask && ((hbase + BITS_PER_LONG) <= hart)) {
+			ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI,
+					hmask, hbase, 0, 0, 0, 0);
+			if (ret.error) {
+				result = sbi_err_map_xen_errno(ret.error);
+				printk("%s: hmask=0x%lx hbase=%lu failed "
+					   "(error %d)\n", __func__, hmask,
+					   hbase, result);
+				return result;
+			}
+			hmask = hbase = 0;
+		}
+		if (!hmask) {
+			hbase = hart;
+		}
+		hmask |= 1UL << (hart - hbase);
+	}
+	if (hmask) {
+		ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI,
+				hmask, hbase, 0, 0, 0, 0);
+		if (ret.error) {
+			result = sbi_err_map_xen_errno(ret.error);
+			printk("%s: hmask=0x%lx hbase=%lu failed "
+				   "(error %d)\n", __func__, hmask,
+				   hbase, result);
+			return result;
+		}
+	}
+
+	return 0;
+}
+
+static int __sbi_rfence_v02_real(unsigned long fid,
+				 unsigned long hmask, unsigned long hbase,
+				 unsigned long start, unsigned long size,
+				 unsigned long arg4)
+{
+	struct sbiret ret = {0};
+	int result = 0;
+
+	switch (fid) {
+	case SBI_EXT_RFENCE_REMOTE_FENCE_I:
+		ret = sbi_ecall(SBI_EXT_RFENCE, fid, hmask, hbase,
+				0, 0, 0, 0);
+		break;
+	case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA:
+		ret = sbi_ecall(SBI_EXT_RFENCE, fid, hmask, hbase,
+				start, size, 0, 0);
+		break;
+	case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID:
+		ret = sbi_ecall(SBI_EXT_RFENCE, fid, hmask, hbase,
+				start, size, arg4, 0);
+		break;
+	case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA:
+		ret = sbi_ecall(SBI_EXT_RFENCE, fid, hmask, hbase,
+				start, size, 0, 0);
+		break;
+	case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID:
+		ret = sbi_ecall(SBI_EXT_RFENCE, fid, hmask, hbase,
+				start, size, arg4, 0);
+		break;
+	case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA:
+		ret = sbi_ecall(SBI_EXT_RFENCE, fid, hmask, hbase,
+				start, size, 0, 0);
+		break;
+	case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID:
+		ret = sbi_ecall(SBI_EXT_RFENCE, fid, hmask, hbase,
+				start, size, arg4, 0);
+		break;
+	default:
+		printk("%s: unknown function ID [%lu]\n",
+			   __func__, fid);
+		result = -EINVAL;
+		break;
+	};
+
+	if (ret.error) {
+		result = sbi_err_map_xen_errno(ret.error);
+		printk("%s: hbase=%lu hmask=0x%lx failed (error %d)\n",
+			   __func__, hbase, hmask, result);
+	}
+
+	return result;
+}
+
+static int __sbi_rfence_v02(unsigned long fid,
+			    const unsigned long *hart_mask,
+			    unsigned long start, unsigned long size,
+			    unsigned long arg4, unsigned long arg5)
+{
+	struct cpumask tmask;
+	unsigned long hart, hmask, hbase;
+	int result;
+
+	if (!hart_mask) {
+		sbi_cpumask_to_hartmask(&cpu_online_map, &tmask);
+		hart_mask = cpumask_bits(&tmask);
+	}
+
+	hmask = hbase = 0;
+	for_each_set_bit(hart, hart_mask, CONFIG_NR_CPUS) {
+		if (hmask && ((hbase + BITS_PER_LONG) <= hart)) {
+			result = __sbi_rfence_v02_real(fid, hmask, hbase,
+							start, size, arg4);
+			if (result)
+				return result;
+			hmask = hbase = 0;
+		}
+		if (!hmask) {
+			hbase = hart;
+		}
+		hmask |= 1UL << (hart - hbase);
+	}
+	if (hmask) {
+		result = __sbi_rfence_v02_real(fid, hmask, hbase,
+						start, size, arg4);
+		if (result)
+			return result;
+	}
+
+	return 0;
+}
+
+static void (*__sbi_set_timer)(u64 stime) = __sbi_set_timer_v01;
+static int (*__sbi_send_ipi)(const unsigned long *hart_mask) =
+						__sbi_send_ipi_v01;
+static int (*__sbi_rfence)(unsigned long fid,
+		const unsigned long *hart_mask,
+		unsigned long start, unsigned long size,
+		unsigned long arg4, unsigned long arg5) = __sbi_rfence_v01;
+
+void sbi_send_ipi(const unsigned long *hart_mask)
+{
+	__sbi_send_ipi(hart_mask);
+}
+
+void sbi_set_timer(u64 stime_value)
+{
+	__sbi_set_timer(stime_value);
+}
+
+void sbi_remote_fence_i(const unsigned long *hart_mask)
+{
+	__sbi_rfence(SBI_EXT_RFENCE_REMOTE_FENCE_I,
+		     hart_mask, 0, 0, 0, 0);
+}
+
+void sbi_remote_sfence_vma(const unsigned long *hart_mask,
+			   unsigned long start,
+			   unsigned long size)
+{
+	__sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA,
+		     hart_mask, start, size, 0, 0);
+}
+
+void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
+				unsigned long start,
+				unsigned long size,
+				unsigned long asid)
+{
+	__sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID,
+		     hart_mask, start, size, asid, 0);
+}
+
+void sbi_remote_hfence_gvma(const unsigned long *hart_mask,
+			    unsigned long start,
+			    unsigned long size)
+{
+	__sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA,
+		     hart_mask, start, size, 0, 0);
+}
+
+void sbi_remote_hfence_gvma_vmid(const unsigned long *hart_mask,
+				 unsigned long start,
+				 unsigned long size,
+				 unsigned long vmid)
+{
+	__sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID,
+		     hart_mask, start, size, vmid, 0);
+}
+
+void sbi_remote_hfence_vvma(const unsigned long *hart_mask,
+			    unsigned long start,
+			    unsigned long size)
+{
+	__sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA,
+		     hart_mask, start, size, 0, 0);
+}
+
+void sbi_remote_hfence_vvma_asid(const unsigned long *hart_mask,
+				 unsigned long start,
+				 unsigned long size,
+				 unsigned long asid)
+{
+	__sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID,
+		     hart_mask, start, size, asid, 0);
+}
+
+static long sbi_ext_base_func(long fid)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0);
+	if (!ret.error)
+		return ret.value;
+	else
+		return ret.error;
+}
+
+#define sbi_get_spec_version()		\
+	sbi_ext_base_func(SBI_EXT_BASE_GET_SPEC_VERSION)
+
+#define sbi_get_firmware_id()		\
+	sbi_ext_base_func(SBI_EXT_BASE_GET_IMP_ID)
+
+#define sbi_get_firmware_version()	\
+	sbi_ext_base_func(SBI_EXT_BASE_GET_IMP_VERSION)
+
+int sbi_probe_extension(long extid)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, extid,
+			0, 0, 0, 0, 0);
+	if (!ret.error && ret.value)
+		return ret.value;
+
+	return -EOPNOTSUPP;
+}
+
+int sbi_spec_is_0_1(void)
+{
+	return (sbi_spec_version == SBI_SPEC_VERSION_DEFAULT) ? 1 : 0;
+}
+
+int sbi_has_0_2_rfence(void)
+{
+	return (__sbi_rfence == __sbi_rfence_v01) ? 0 : 1;
+}
+
+unsigned long sbi_major_version(void)
+{
+	return (sbi_spec_version >> SBI_SPEC_VERSION_MAJOR_SHIFT) &
+		SBI_SPEC_VERSION_MAJOR_MASK;
+}
+
+unsigned long sbi_minor_version(void)
+{
+	return sbi_spec_version & SBI_SPEC_VERSION_MINOR_MASK;
+}
+
+int __init sbi_init(void)
+{
+	int ret;
+
+	ret = sbi_get_spec_version();
+	if (ret > 0)
+		sbi_spec_version = ret;
+
+	printk("SBI specification v%lu.%lu detected\n",
+			sbi_major_version(), sbi_minor_version());
+
+	if (!sbi_spec_is_0_1()) {
+		printk("SBI implementation ID=0x%lx Version=0x%lx\n",
+			sbi_get_firmware_id(), sbi_get_firmware_version());
+		if (sbi_probe_extension(SBI_EXT_TIME) > 0) {
+			__sbi_set_timer = __sbi_set_timer_v02;
+			printk("SBI v0.2 TIME extension detected\n");
+		}
+		if (sbi_probe_extension(SBI_EXT_IPI) > 0) {
+			__sbi_send_ipi = __sbi_send_ipi_v02;
+			printk("SBI v0.2 IPI extension detected\n");
+		}
+		if (sbi_probe_extension(SBI_EXT_RFENCE) > 0) {
+			__sbi_rfence = __sbi_rfence_v02;
+			printk("SBI v0.2 RFENCE extension detected\n");
+		}
+	}
+
+	if (!sbi_has_0_2_rfence()) {
+		printk("WARNING: SBI v0.2 RFENCE not available !\n");
+	}
+
+	return 0;
+}
+
+__initcall(sbi_init);
-- 
2.30.2
Re: [RFC PATCH 4/6] xen/riscv: Add sbi.c, sbi.h
Posted by Jan Beulich 3 years, 6 months ago
On 31.05.2022 08:57, Xie Xun wrote:
> Signed-off-by: Xie Xun <xiexun162534@gmail.com>

Is this correct / complete, considering ....

> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/sbi.h
> @@ -0,0 +1,275 @@
> +/**
> + * Copyright (c) 2021 Vates SAS.
> + *
> + * Taken from xvisor, modified by Bobby Eshleman (bobby.eshleman@gmail.com).

... this?

Jan
Re: [RFC PATCH 4/6] xen/riscv: Add sbi.c, sbi.h
Posted by Xie Xun 3 years, 6 months ago
Hi Jan,

On Tue, 31 May 2022 at 15:54, Jan Beulich <jbeulich@suse.com> wrote:
>
> On 31.05.2022 08:57, Xie Xun wrote:
> > Signed-off-by: Xie Xun <xiexun162534@gmail.com>
>
> Is this correct / complete, considering ....

Thank you for pointing out this problem.

I have read the submitting guide
https://wiki.xenproject.org/wiki/Submitting_Xen_Project_Patches#Signed-off-by

and it says that signed-off-by indicates I certify the patch under the
"Developer's
Certificate of Origins".
And in the "Developer's Certificate of Origins":
        (b) The contribution is based upon previous work that, to the best
            of my knowledge, is covered under an appropriate open source
            license and I have the right under that license to submit that
            work with modifications, whether created in whole or in part
            by me, under the same open source license (unless I am
            permitted to submit under a different license), as indicated
            in the file; or

Because Xvisor is also distributed under GPL, i think it will be
correct if it is
signed-off-by Bobby. The problem is that I did not modify this part of the code,
so I want to know how to submit this patch in a correct way?

Thank you for replying.



>
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/sbi.h
> > @@ -0,0 +1,275 @@
> > +/**
> > + * Copyright (c) 2021 Vates SAS.
> > + *
> > + * Taken from xvisor, modified by Bobby Eshleman (bobby.eshleman@gmail.com).
>
> ... this?
>
> Jan
>
Re: [RFC PATCH 4/6] xen/riscv: Add sbi.c, sbi.h
Posted by Jan Beulich 3 years, 6 months ago
On 31.05.2022 10:59, Xie Xun wrote:
> On Tue, 31 May 2022 at 15:54, Jan Beulich <jbeulich@suse.com> wrote:
>> On 31.05.2022 08:57, Xie Xun wrote:
>>> Signed-off-by: Xie Xun <xiexun162534@gmail.com>
>>
>> Is this correct / complete, considering ....
> 
> Thank you for pointing out this problem.
> 
> I have read the submitting guide
> https://wiki.xenproject.org/wiki/Submitting_Xen_Project_Patches#Signed-off-by
> 
> and it says that signed-off-by indicates I certify the patch under the
> "Developer's
> Certificate of Origins".
> And in the "Developer's Certificate of Origins":
>         (b) The contribution is based upon previous work that, to the best
>             of my knowledge, is covered under an appropriate open source
>             license and I have the right under that license to submit that
>             work with modifications, whether created in whole or in part
>             by me, under the same open source license (unless I am
>             permitted to submit under a different license), as indicated
>             in the file; or
> 
> Because Xvisor is also distributed under GPL, i think it will be
> correct if it is
> signed-off-by Bobby. The problem is that I did not modify this part of the code,
> so I want to know how to submit this patch in a correct way?

If you didn't alter this patch at all (or just minimally), then I guess
first of all you want to set From: to Bob. Whether he has given his
S-o-b of the code I don't know; hence my earlier question. If so, having
his first and then yours is quite usual an arrangement.

Jan