From owner-svn-src-head@freebsd.org Mon Oct 26 19:13:23 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 45F4B44C6B5; Mon, 26 Oct 2020 19:13:23 +0000 (UTC) (envelope-from mhorne@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CKkyC14ffz4cmP; Mon, 26 Oct 2020 19:13:23 +0000 (UTC) (envelope-from mhorne@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 082C91F265; Mon, 26 Oct 2020 19:13:23 +0000 (UTC) (envelope-from mhorne@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 09QJDMEP080786; Mon, 26 Oct 2020 19:13:22 GMT (envelope-from mhorne@FreeBSD.org) Received: (from mhorne@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 09QJDMmB080784; Mon, 26 Oct 2020 19:13:22 GMT (envelope-from mhorne@FreeBSD.org) Message-Id: <202010261913.09QJDMmB080784@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mhorne set sender to mhorne@FreeBSD.org using -f From: Mitchell Horne Date: Mon, 26 Oct 2020 19:13:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r367068 - in head/sys/riscv: include riscv X-SVN-Group: head X-SVN-Commit-Author: mhorne X-SVN-Commit-Paths: in head/sys/riscv: include riscv X-SVN-Commit-Revision: 367068 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Oct 2020 19:13:23 -0000 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. 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()"));