svn commit: r367068 - in head/sys/riscv: include riscv

Mitchell Horne mhorne at FreeBSD.org
Mon Oct 26 19:13:23 UTC 2020


Author: mhorne
Date: Mon Oct 26 19:13:22 2020
New Revision: 367068
URL: https://svnweb.freebsd.org/changeset/base/367068

Log:
  riscv: make use of SBI legacy replacement extensions
  
  Version 0.2 of the SBI specification [1] marked the existing SBI
  functions as "legacy" in order to move to a newer calling convention. It
  also introduced a set of replacement extensions for some of the legacy
  functionality. In particular, the TIME, IPI, and RFENCE extensions
  implement and extend the semantics of their legacy counterparts, while
  conforming to the newer version of the spec.
  
  Update our SBI code to use the new replacement extensions when
  available, and fall back to the legacy ones. These will eventually be
  dropped, when support for version 0.2 is ubiquitous.
  
  [1] https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc
  
  Submitted by:	Danjel Q. <danq1222 at gmail.com>
  Reviewed by:	kp
  Differential Revision:	https://reviews.freebsd.org/D26953

Modified:
  head/sys/riscv/include/sbi.h
  head/sys/riscv/riscv/sbi.c

Modified: head/sys/riscv/include/sbi.h
==============================================================================
--- head/sys/riscv/include/sbi.h	Mon Oct 26 19:06:30 2020	(r367067)
+++ head/sys/riscv/include/sbi.h	Mon Oct 26 19:13:22 2020	(r367068)
@@ -67,6 +67,24 @@
 #define	SBI_BASE_GET_MARCHID		5
 #define	SBI_BASE_GET_MIMPID		6
 
+/* Timer (TIME) Extension */
+#define	SBI_EXT_ID_TIME			0x54494D45
+#define	SBI_TIME_SET_TIMER		0
+
+/* IPI (IPI) Extension */
+#define	SBI_EXT_ID_IPI			0x735049
+#define	SBI_IPI_SEND_IPI		0
+
+/* RFENCE (RFNC) Extension */
+#define	SBI_EXT_ID_RFNC				0x52464E43
+#define	SBI_RFNC_REMOTE_FENCE_I			0
+#define	SBI_RFNC_REMOTE_SFENCE_VMA		1
+#define	SBI_RFNC_REMOTE_SFENCE_VMA_ASID		2
+#define	SBI_RFNC_REMOTE_HFENCE_GVMA_VMID	3
+#define	SBI_RFNC_REMOTE_HFENCE_GVMA		4
+#define	SBI_RFNC_REMOTE_HFENCE_VVMA_ASID	5
+#define	SBI_RFNC_REMOTE_HFENCE_VVMA		6
+
 /* Hart State Management (HSM) Extension */
 #define	SBI_EXT_ID_HSM			0x48534D
 #define	SBI_HSM_HART_START		0
@@ -88,11 +106,12 @@
 #define	SBI_REMOTE_SFENCE_VMA_ASID	7
 #define	SBI_SHUTDOWN			8
 
-#define	SBI_CALL0(e, f)			SBI_CALL4(e, f, 0, 0, 0, 0)
-#define	SBI_CALL1(e, f, p1)		SBI_CALL4(e, f, p1, 0, 0, 0)
-#define	SBI_CALL2(e, f, p1, p2)		SBI_CALL4(e, f, p1, p2, 0, 0)
-#define	SBI_CALL3(e, f, p1, p2, p3)	SBI_CALL4(e, f, p1, p2, p3, 0)
-#define	SBI_CALL4(e, f, p1, p2, p3, p4)	sbi_call(e, f, p1, p2, p3, p4)
+#define	SBI_CALL0(e, f)				SBI_CALL5(e, f, 0, 0, 0, 0, 0)
+#define	SBI_CALL1(e, f, p1)			SBI_CALL5(e, f, p1, 0, 0, 0, 0)
+#define	SBI_CALL2(e, f, p1, p2)			SBI_CALL5(e, f, p1, p2, 0, 0, 0)
+#define	SBI_CALL3(e, f, p1, p2, p3)		SBI_CALL5(e, f, p1, p2, p3, 0, 0)
+#define	SBI_CALL4(e, f, p1, p2, p3, p4)		SBI_CALL5(e, f, p1, p2, p3, p4, 0)
+#define	SBI_CALL5(e, f, p1, p2, p3, p4, p5)	sbi_call(e, f, p1, p2, p3, p4, p5)
 
 /*
  * Documentation available at
@@ -106,7 +125,7 @@ struct sbi_ret {
 
 static __inline struct sbi_ret
 sbi_call(uint64_t arg7, uint64_t arg6, uint64_t arg0, uint64_t arg1,
-    uint64_t arg2, uint64_t arg3)
+    uint64_t arg2, uint64_t arg3, uint64_t arg4)
 {
 	struct sbi_ret ret;
 
@@ -114,13 +133,14 @@ sbi_call(uint64_t arg7, uint64_t arg6, uint64_t arg0, 
 	register uintptr_t a1 __asm ("a1") = (uintptr_t)(arg1);
 	register uintptr_t a2 __asm ("a2") = (uintptr_t)(arg2);
 	register uintptr_t a3 __asm ("a3") = (uintptr_t)(arg3);
+	register uintptr_t a4 __asm ("a4") = (uintptr_t)(arg4);
 	register uintptr_t a6 __asm ("a6") = (uintptr_t)(arg6);
 	register uintptr_t a7 __asm ("a7") = (uintptr_t)(arg7);
 
 	__asm __volatile(			\
 		"ecall"				\
 		:"+r"(a0), "+r"(a1)		\
-		:"r"(a2), "r"(a3), "r"(a6), "r"(a7)	\
+		:"r"(a2), "r"(a3), "r"(a4), "r"(a6), "r"(a7)	\
 		:"memory");
 
 	ret.error = a0;
@@ -139,6 +159,18 @@ sbi_probe_extension(long id)
 	return (SBI_CALL1(SBI_EXT_ID_BASE, SBI_BASE_PROBE_EXTENSION, id).value);
 }
 
+/* TIME extension functions. */
+void sbi_set_timer(uint64_t val);
+
+/* IPI extension functions. */
+void sbi_send_ipi(const u_long *hart_mask);
+
+/* RFENCE extension functions. */
+void sbi_remote_fence_i(const u_long *hart_mask);
+void sbi_remote_sfence_vma(const u_long *hart_mask, u_long start, u_long size);
+void sbi_remote_sfence_vma_asid(const u_long *hart_mask, u_long start,
+    u_long size, u_long asid);
+
 /* Hart State Management extension functions. */
 
 /*
@@ -183,50 +215,10 @@ sbi_console_getchar(void)
 }
 
 static __inline void
-sbi_set_timer(uint64_t val)
-{
-
-	(void)SBI_CALL1(SBI_SET_TIMER, 0, val);
-}
-
-static __inline void
 sbi_shutdown(void)
 {
 
 	(void)SBI_CALL0(SBI_SHUTDOWN, 0);
-}
-
-static __inline void
-sbi_send_ipi(const unsigned long *hart_mask)
-{
-
-	(void)SBI_CALL1(SBI_SEND_IPI, 0, (uint64_t)hart_mask);
-}
-
-static __inline void
-sbi_remote_fence_i(const unsigned long *hart_mask)
-{
-
-	(void)SBI_CALL1(SBI_REMOTE_FENCE_I, 0, (uint64_t)hart_mask);
-}
-
-static __inline void
-sbi_remote_sfence_vma(const unsigned long *hart_mask,
-    unsigned long start, unsigned long size)
-{
-
-	(void)SBI_CALL3(SBI_REMOTE_SFENCE_VMA, 0, (uint64_t)hart_mask, start,
-	    size);
-}
-
-static __inline void
-sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
-    unsigned long start, unsigned long size,
-    unsigned long asid)
-{
-
-	(void)SBI_CALL4(SBI_REMOTE_SFENCE_VMA_ASID, 0, (uint64_t)hart_mask,
-	    start, size, asid);
 }
 
 void sbi_print_version(void);

Modified: head/sys/riscv/riscv/sbi.c
==============================================================================
--- head/sys/riscv/riscv/sbi.c	Mon Oct 26 19:06:30 2020	(r367067)
+++ head/sys/riscv/riscv/sbi.c	Mon Oct 26 19:13:22 2020	(r367068)
@@ -46,6 +46,10 @@ u_long sbi_spec_version;
 u_long sbi_impl_id;
 u_long sbi_impl_version;
 
+static bool has_time_extension = false;
+static bool has_ipi_extension = false;
+static bool has_rfnc_extension = false;
+
 static struct sbi_ret
 sbi_get_spec_version(void)
 {
@@ -122,6 +126,83 @@ sbi_print_version(void)
 	printf("SBI Specification Version: %u.%u\n", major, minor);
 }
 
+void
+sbi_set_timer(uint64_t val)
+{
+	struct sbi_ret ret;
+
+	/* Use the TIME legacy replacement extension, if available. */
+	if (has_time_extension) {
+		ret = SBI_CALL1(SBI_EXT_ID_TIME, SBI_TIME_SET_TIMER, val);
+		MPASS(ret.error == SBI_SUCCESS);
+	} else {
+		(void)SBI_CALL1(SBI_SET_TIMER, 0, val);
+	}
+}
+
+void
+sbi_send_ipi(const u_long *hart_mask)
+{
+	struct sbi_ret ret;
+
+	/* Use the IPI legacy replacement extension, if available. */
+	if (has_ipi_extension) {
+		ret = SBI_CALL2(SBI_EXT_ID_IPI, SBI_IPI_SEND_IPI,
+		    *hart_mask, 0);
+		MPASS(ret.error == SBI_SUCCESS);
+	} else {
+		(void)SBI_CALL1(SBI_SEND_IPI, 0, (uint64_t)hart_mask);
+	}
+}
+
+void
+sbi_remote_fence_i(const u_long *hart_mask)
+{
+	struct sbi_ret ret;
+
+	/* Use the RFENCE legacy replacement extension, if available. */
+	if (has_rfnc_extension) {
+		ret = SBI_CALL2(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_FENCE_I,
+		    *hart_mask, 0);
+		MPASS(ret.error == SBI_SUCCESS);
+	} else {
+		(void)SBI_CALL1(SBI_REMOTE_FENCE_I, 0, (uint64_t)hart_mask);
+	}
+}
+
+void
+sbi_remote_sfence_vma(const u_long *hart_mask, u_long start, u_long size)
+{
+	struct sbi_ret ret;
+
+	/* Use the RFENCE legacy replacement extension, if available. */
+	if (has_rfnc_extension) {
+		ret = SBI_CALL4(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_SFENCE_VMA,
+		    *hart_mask, 0, start, size);
+		MPASS(ret.error == SBI_SUCCESS);
+	} else {
+		(void)SBI_CALL3(SBI_REMOTE_SFENCE_VMA, 0, (uint64_t)hart_mask,
+		    start, size);
+	}
+}
+
+void
+sbi_remote_sfence_vma_asid(const u_long *hart_mask, u_long start, u_long size,
+    u_long asid)
+{
+	struct sbi_ret ret;
+
+	/* Use the RFENCE legacy replacement extension, if available. */
+	if (has_rfnc_extension) {
+		ret = SBI_CALL5(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_SFENCE_VMA_ASID,
+		    *hart_mask, 0, start, size, asid);
+		MPASS(ret.error == SBI_SUCCESS);
+	} else {
+		(void)SBI_CALL4(SBI_REMOTE_SFENCE_VMA_ASID, 0,
+		    (uint64_t)hart_mask, start, size, asid);
+	}
+}
+
 int
 sbi_hsm_hart_start(u_long hart, u_long start_addr, u_long priv)
 {
@@ -173,23 +254,34 @@ sbi_init(void)
 	marchid = sbi_get_marchid().value;
 	mimpid = sbi_get_mimpid().value;
 
+	/* Probe for legacy replacement extensions. */
+	if (sbi_probe_extension(SBI_EXT_ID_TIME) != 0)
+		has_time_extension = true;
+	if (sbi_probe_extension(SBI_EXT_ID_IPI) != 0)
+		has_ipi_extension = true;
+	if (sbi_probe_extension(SBI_EXT_ID_RFNC) != 0)
+		has_rfnc_extension = true;
+
 	/*
-	 * Probe for legacy extensions. Currently we rely on all of them
-	 * to be implemented, but this is not guaranteed by the spec.
+	 * Probe for legacy extensions. We still rely on many of them to be
+	 * implemented, but this is not guaranteed by the spec.
 	 */
-	KASSERT(sbi_probe_extension(SBI_SET_TIMER) != 0,
+	KASSERT(has_time_extension || sbi_probe_extension(SBI_SET_TIMER) != 0,
 	    ("SBI doesn't implement sbi_set_timer()"));
 	KASSERT(sbi_probe_extension(SBI_CONSOLE_PUTCHAR) != 0,
 	    ("SBI doesn't implement sbi_console_putchar()"));
 	KASSERT(sbi_probe_extension(SBI_CONSOLE_GETCHAR) != 0,
 	    ("SBI doesn't implement sbi_console_getchar()"));
-	KASSERT(sbi_probe_extension(SBI_SEND_IPI) != 0,
+	KASSERT(has_ipi_extension || sbi_probe_extension(SBI_SEND_IPI) != 0,
 	    ("SBI doesn't implement sbi_send_ipi()"));
-	KASSERT(sbi_probe_extension(SBI_REMOTE_FENCE_I) != 0,
+	KASSERT(has_rfnc_extension ||
+	    sbi_probe_extension(SBI_REMOTE_FENCE_I) != 0,
 	    ("SBI doesn't implement sbi_remote_fence_i()"));
-	KASSERT(sbi_probe_extension(SBI_REMOTE_SFENCE_VMA) != 0,
+	KASSERT(has_rfnc_extension ||
+	    sbi_probe_extension(SBI_REMOTE_SFENCE_VMA) != 0,
 	    ("SBI doesn't implement sbi_remote_sfence_vma()"));
-	KASSERT(sbi_probe_extension(SBI_REMOTE_SFENCE_VMA_ASID) != 0,
+	KASSERT(has_rfnc_extension ||
+	    sbi_probe_extension(SBI_REMOTE_SFENCE_VMA_ASID) != 0,
 	    ("SBI doesn't implement sbi_remote_sfence_vma_asid()"));
 	KASSERT(sbi_probe_extension(SBI_SHUTDOWN) != 0,
 	    ("SBI doesn't implement sbi_shutdown()"));


More information about the svn-src-all mailing list