Module Name:    src
Committed By:   jmcneill
Date:           Sat Oct 30 18:44:24 UTC 2021

Modified Files:
        src/sys/arch/aarch64/conf: files.aarch64
        src/sys/arch/arm/cortex: gic_splfuncs.c
Added Files:
        src/sys/arch/arm/cortex: gic_splfuncs_armv8.S

Log Message:
Implement gic_splraise and the gic_splx fast path in asm (armv8).


To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/aarch64/conf/files.aarch64
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/cortex/gic_splfuncs.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/cortex/gic_splfuncs_armv8.S

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/aarch64/conf/files.aarch64
diff -u src/sys/arch/aarch64/conf/files.aarch64:1.34 src/sys/arch/aarch64/conf/files.aarch64:1.35
--- src/sys/arch/aarch64/conf/files.aarch64:1.34	Sun Oct 10 07:15:25 2021
+++ src/sys/arch/aarch64/conf/files.aarch64	Sat Oct 30 18:44:24 2021
@@ -1,4 +1,4 @@
-#	$NetBSD: files.aarch64,v 1.34 2021/10/10 07:15:25 skrll Exp $
+#	$NetBSD: files.aarch64,v 1.35 2021/10/30 18:44:24 jmcneill Exp $
 
 defflag opt_cpuoptions.h	AARCH64_ALIGNMENT_CHECK
 defflag opt_cpuoptions.h	AARCH64_EL0_STACK_ALIGNMENT_CHECK
@@ -119,6 +119,9 @@ file	arch/aarch64/aarch64/pmap_page.S
 file	uvm/pmap/pmap_tlb.c
 file	uvm/pmap/pmap_pvt.c
 
+# GIC
+file	arch/arm/cortex/gic_splfuncs_armv8.S		gic_splfuncs
+
 # EFI runtime (machdep)
 file	arch/aarch64/aarch64/efi_machdep.c		efi_runtime
 

Index: src/sys/arch/arm/cortex/gic_splfuncs.c
diff -u src/sys/arch/arm/cortex/gic_splfuncs.c:1.4 src/sys/arch/arm/cortex/gic_splfuncs.c:1.5
--- src/sys/arch/arm/cortex/gic_splfuncs.c:1.4	Sun Sep 26 20:55:15 2021
+++ src/sys/arch/arm/cortex/gic_splfuncs.c	Sat Oct 30 18:44:24 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: gic_splfuncs.c,v 1.4 2021/09/26 20:55:15 jmcneill Exp $ */
+/* $NetBSD: gic_splfuncs.c,v 1.5 2021/10/30 18:44:24 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2021 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gic_splfuncs.c,v 1.4 2021/09/26 20:55:15 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gic_splfuncs.c,v 1.5 2021/10/30 18:44:24 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -41,16 +41,12 @@ __KERNEL_RCSID(0, "$NetBSD: gic_splfuncs
 
 #include <arm/cortex/gic_splfuncs.h>
 
-static int
-gic_splraise(int newipl)
-{
-	struct cpu_info * const ci = curcpu();
-	const int oldipl = ci->ci_cpl;
-	if (__predict_true(newipl > oldipl)) {
-		ci->ci_cpl = newipl;
-	}
-	return oldipl;
-}
+/* Prototypes for functions in gic_splfuncs_<arch>.S */
+int	gic_splraise(int);
+void	gic_splx(int);
+
+/* Local functions */
+void	Xgic_splx(int);	
 
 static int
 gic_spllower(int newipl)
@@ -72,8 +68,8 @@ gic_spllower(int newipl)
 	return oldipl;
 }
 
-static void
-gic_splx(int newipl)
+void
+Xgic_splx(int newipl)
 {
 	struct cpu_info *ci = curcpu();
 	register_t psw;
@@ -82,37 +78,6 @@ gic_splx(int newipl)
 		return;
 	}
 
-	/*
-	 * Try to avoid touching any hardware registers (DAIF, PMR) as an
-	 * optimization for the common case of splraise followed by splx
-	 * with no interrupts in between.
-	 *
-	 * If an interrupt fires in this critical section, the vector
-	 * handler is responsible for returning to the address pointed
-	 * to by ci_splx_restart to restart the sequence.
-	 */
-	if (__predict_true(ci->ci_intr_depth == 0)) {
-		ci->ci_splx_savedipl = newipl;
-		__insn_barrier();
-		ci->ci_splx_restart = &&restart;
-		__insn_barrier();
-checkhwpl:
-		if (ci->ci_hwpl <= newipl) {
-			ci->ci_cpl = newipl;
-			__insn_barrier();
-			ci->ci_splx_restart = NULL;
-			goto dosoft;
-		} else {
-			ci->ci_splx_restart = NULL;
-			goto dohard;
-		}
-restart:
-		ci = curcpu();
-		newipl = ci->ci_splx_savedipl;
-		goto checkhwpl;
-	}
-
-dohard:
 	psw = DISABLE_INTERRUPT_SAVE();
 	ci->ci_intr_depth++;
 	pic_do_pending_ints(psw, newipl, NULL);
@@ -121,7 +86,6 @@ dohard:
 		ENABLE_INTERRUPT();
 	}
 
-dosoft:
 	cpu_dosoftints();
 }
 

Added files:

Index: src/sys/arch/arm/cortex/gic_splfuncs_armv8.S
diff -u /dev/null src/sys/arch/arm/cortex/gic_splfuncs_armv8.S:1.1
--- /dev/null	Sat Oct 30 18:44:24 2021
+++ src/sys/arch/arm/cortex/gic_splfuncs_armv8.S	Sat Oct 30 18:44:24 2021
@@ -0,0 +1,118 @@
+/* $NetBSD: gic_splfuncs_armv8.S,v 1.1 2021/10/30 18:44:24 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2021 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+#include "assym.h"
+
+RCSID("$NetBSD: gic_splfuncs_armv8.S,v 1.1 2021/10/30 18:44:24 jmcneill Exp $")
+
+/*
+ * int
+ * gic_splraise(int newipl)
+ *
+ *	w0 = newipl
+ */
+	.align 7        /* cacheline-aligned */
+ENTRY_NP(gic_splraise)
+	/* Save cpu_info pointer in x1 */
+	mrs	x1, tpidr_el1			/* get curlwp */
+	ldr	x1, [x1, #L_CPU]		/* get curcpu */
+
+	/* If newipl > cpl, update cpl */
+	ldr	w2, [x1, #CI_CPL]
+	cmp	w0, w2
+	b.le	.Lnoraise
+	str	w0, [x1, #CI_CPL]
+
+.Lnoraise:
+	mov	w0, w2				/* return oldipl */
+	ret
+END(gic_splraise)
+
+
+/*
+ * void
+ * gic_splx(int newipl)
+ *
+ *	w0 = newipl
+ */
+	.align 7        /* cacheline-aligned */
+ENTRY_NP(gic_splx)
+	/* Save cpu_info pointer in x1 */
+	mrs	x1, tpidr_el1			/* get curlwp */
+	ldr	x1, [x1, #L_CPU]		/* get curcpu */
+
+	/* If newipl >= cpl, just return */
+	ldr	w2, [x1, #CI_CPL]
+	cmp	w0, w2
+	b.hs	.Ldone
+
+.Lagain:
+	/* Slow path if ci_intr_depth != 0 */
+	ldr	w2, [x1, #CI_INTR_DEPTH]
+	cbnz	w2, .Lslow
+
+	/* Save newipl and restart address in cpu info */
+	str	w0, [x1, #CI_SPLX_SAVEDIPL]
+	adr	x2, .Lrestart
+	str	x2, [x1, #CI_SPLX_RESTART]
+
+	/* Slow path if hwpl > newipl */
+	ldr	w2, [x1, #CI_HWPL]
+	cmp	w2, w0
+	b.hi	.Lrestore
+
+	/* Update cpl */
+	str	w0, [x1, #CI_CPL]
+
+	/* Clear saved restart address from cpu info */
+	str	xzr, [x1, #CI_SPLX_RESTART]
+
+	/* Check for pending softints */
+	ldr	w2, [x1, #CI_SOFTINTS]
+	lsr	w2, w2, w0
+	cbnz	w2, _C_LABEL(dosoftints)
+
+.Ldone:
+	ret
+
+.Lrestart:
+	/* Reload w0 and x1 */
+	mrs	x1, tpidr_el1			/* get curlwp */
+	ldr	x1, [x1, #L_CPU]		/* get curcpu */
+	ldr	w0, [x1, #CI_SPLX_SAVEDIPL]	/* get newipl */
+	b	.Lagain
+	
+.Lrestore:
+	/* Clear saved restart address from cpu info */
+	str	xzr, [x1, #CI_SPLX_RESTART]
+
+.Lslow:
+	/* Jump to slow path */
+	b	_C_LABEL(Xgic_splx)
+END(gic_splx)

Reply via email to