Module Name:    src
Committed By:   jmcneill
Date:           Tue Aug 10 15:33:09 UTC 2021

Modified Files:
        src/sys/arch/arm/cortex: files.cortex gic.c gicv3.c
Added Files:
        src/sys/arch/arm/cortex: gic_splfuncs.c gic_splfuncs.h

Log Message:
Use custom spl funcs for GIC and avoid unnecessary pmr register accesses
in splx.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/cortex/files.cortex
cvs rdiff -u -r1.47 -r1.48 src/sys/arch/arm/cortex/gic.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/cortex/gic_splfuncs.c \
    src/sys/arch/arm/cortex/gic_splfuncs.h
cvs rdiff -u -r1.44 -r1.45 src/sys/arch/arm/cortex/gicv3.c

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/arm/cortex/files.cortex
diff -u src/sys/arch/arm/cortex/files.cortex:1.14 src/sys/arch/arm/cortex/files.cortex:1.15
--- src/sys/arch/arm/cortex/files.cortex:1.14	Tue Sep 29 19:58:50 2020
+++ src/sys/arch/arm/cortex/files.cortex	Tue Aug 10 15:33:09 2021
@@ -1,4 +1,4 @@
-# $NetBSD: files.cortex,v 1.14 2020/09/29 19:58:50 jmcneill Exp $
+# $NetBSD: files.cortex,v 1.15 2021/08/10 15:33:09 jmcneill Exp $
 
 defflag opt_cpu_in_cksum.h			NEON_IN_CKSUM
 
@@ -11,13 +11,16 @@ device	armperiph: mpcorebus
 attach	armperiph at mainbus
 file	arch/arm/cortex/armperiph.c		armperiph
 
+define	gic_splfuncs
+file	arch/arm/cortex/gic_splfuncs.c		gic_splfuncs
+
 # ARM Generic Interrupt Controller (initially on Cortex-A9)
-device	armgic: pic, pic_splfuncs
+device	armgic: pic, pic_splfuncs, gic_splfuncs
 attach	armgic at mpcorebus
 file	arch/arm/cortex/gic.c			armgic
 
 # ARM Generic Interrupt Controller v3+
-device	gicvthree: pic, pic_splfuncs
+device	gicvthree: pic, pic_splfuncs, gic_splfuncs
 file	arch/arm/cortex/gicv3.c			gicvthree
 file	arch/arm/cortex/gicv3_its.c		gicvthree & pci & __have_pci_msi_msix
 

Index: src/sys/arch/arm/cortex/gic.c
diff -u src/sys/arch/arm/cortex/gic.c:1.47 src/sys/arch/arm/cortex/gic.c:1.48
--- src/sys/arch/arm/cortex/gic.c:1.47	Sun Mar 28 09:11:38 2021
+++ src/sys/arch/arm/cortex/gic.c	Tue Aug 10 15:33:09 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: gic.c,v 1.47 2021/03/28 09:11:38 skrll Exp $	*/
+/*	$NetBSD: gic.c,v 1.48 2021/08/10 15:33:09 jmcneill Exp $	*/
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -34,7 +34,7 @@
 #define _INTR_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.47 2021/03/28 09:11:38 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.48 2021/08/10 15:33:09 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.47
 #include <arm/locore.h>
 
 #include <arm/cortex/gic_reg.h>
+#include <arm/cortex/gic_splfuncs.h>
 #include <arm/cortex/mpcore_var.h>
 
 void armgic_irq_handler(void *);
@@ -224,11 +225,10 @@ armgic_set_priority(struct pic_softc *pi
 	struct armgic_softc * const sc = PICTOSOFTC(pic);
 	struct cpu_info * const ci = curcpu();
 
-	const uint32_t priority = armgic_ipl_to_priority(ipl);
-	if (priority > ci->ci_hwpl) {
+	if (ipl < ci->ci_hwpl) {
 		/* Lowering priority mask */
-		ci->ci_hwpl = priority;
-		gicc_write(sc, GICC_PMR, priority);
+		ci->ci_hwpl = ipl;
+		gicc_write(sc, GICC_PMR, armgic_ipl_to_priority(ipl));
 	}
 }
 
@@ -327,10 +327,9 @@ armgic_irq_handler(void *tf)
 
 	ci->ci_data.cpu_nintr++;
 
-	const uint32_t priority = armgic_ipl_to_priority(old_ipl);
-	if (ci->ci_hwpl != priority) {
-		ci->ci_hwpl = priority;
-		gicc_write(sc, GICC_PMR, priority);
+	if (ci->ci_hwpl != old_ipl) {
+		ci->ci_hwpl = old_ipl;
+		gicc_write(sc, GICC_PMR, armgic_ipl_to_priority(old_ipl));
 		if (old_ipl == IPL_HIGH) {
 			return;
 		}
@@ -545,7 +544,7 @@ armgic_cpu_init(struct pic_softc *pic, s
 			    sc->sc_enabled_local);
 		}
 	}
-	ci->ci_hwpl = armgic_ipl_to_priority(ci->ci_cpl);
+	ci->ci_hwpl = ci->ci_cpl;
 	gicc_write(sc, GICC_PMR, armgic_ipl_to_priority(ci->ci_cpl));	// set PMR
 	gicc_write(sc, GICC_CTRL, GICC_CTRL_V1_Enable);	// enable interrupt
 	ENABLE_INTERRUPT();				// allow IRQ exceptions
@@ -730,6 +729,8 @@ armgic_attach(device_t parent, device_t 
 	aprint_normal_dev(sc->sc_dev, "%u Priorities, %zu SPIs, %u PPIs, "
 	    "%u SGIs\n",  priorities, sc->sc_gic_lines - ppis - sgis, ppis,
 	    sgis);
+
+	gic_spl_init();
 }
 
 CFATTACH_DECL_NEW(armgic, 0,

Index: src/sys/arch/arm/cortex/gicv3.c
diff -u src/sys/arch/arm/cortex/gicv3.c:1.44 src/sys/arch/arm/cortex/gicv3.c:1.45
--- src/sys/arch/arm/cortex/gicv3.c:1.44	Sun Mar 28 11:13:24 2021
+++ src/sys/arch/arm/cortex/gicv3.c	Tue Aug 10 15:33:09 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: gicv3.c,v 1.44 2021/03/28 11:13:24 jmcneill Exp $ */
+/* $NetBSD: gicv3.c,v 1.45 2021/08/10 15:33:09 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -31,7 +31,7 @@
 #define	_INTR_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.44 2021/03/28 11:13:24 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.45 2021/08/10 15:33:09 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -51,6 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.
 
 #include <arm/cortex/gicv3.h>
 #include <arm/cortex/gic_reg.h>
+#include <arm/cortex/gic_splfuncs.h>
 
 #define	PICTOSOFTC(pic)	\
 	((void *)((uintptr_t)(pic) - offsetof(struct gicv3_softc, sc_pic)))
@@ -230,12 +231,11 @@ gicv3_set_priority(struct pic_softc *pic
 {
 	struct gicv3_softc * const sc = PICTOSOFTC(pic);
 	struct cpu_info * const ci = curcpu();
-	const uint8_t newpmr = IPL_TO_PMR(sc, ipl);
 
-	if (newpmr > ci->ci_hwpl) {
+	if (ipl < ci->ci_hwpl) {
 		/* Lowering priority mask */
-		ci->ci_hwpl = newpmr;
-		icc_pmr_write(newpmr);
+		ci->ci_hwpl = ipl;
+		icc_pmr_write(IPL_TO_PMR(sc, ipl));
 	}
 }
 
@@ -422,8 +422,8 @@ gicv3_cpu_init(struct pic_softc *pic, st
 		;
 
 	/* Set initial priority mask */
-	ci->ci_hwpl = IPL_TO_PMR(sc, IPL_HIGH);
-	icc_pmr_write(ci->ci_hwpl);
+	ci->ci_hwpl = IPL_HIGH;
+	icc_pmr_write(IPL_TO_PMR(sc, IPL_HIGH));
 
 	/* Set the binary point field to the minimum value */
 	icc_bpr1_write(0);
@@ -738,13 +738,12 @@ gicv3_irq_handler(void *frame)
 	struct gicv3_softc * const sc = gicv3_softc;
 	struct pic_softc *pic;
 	const int oldipl = ci->ci_cpl;
-	const uint8_t pmr = IPL_TO_PMR(sc, oldipl);
 
 	ci->ci_data.cpu_nintr++;
 
-	if (ci->ci_hwpl != pmr) {
-		ci->ci_hwpl = pmr;
-		icc_pmr_write(pmr);
+	if (ci->ci_hwpl != oldipl) {
+		ci->ci_hwpl = oldipl;
+		icc_pmr_write(IPL_TO_PMR(sc, oldipl));
 		if (oldipl == IPL_HIGH) {
 			return;
 		}
@@ -953,5 +952,7 @@ gicv3_init(struct gicv3_softc *sc)
 #endif
 #endif
 
+	gic_spl_init();
+
 	return 0;
 }

Added files:

Index: src/sys/arch/arm/cortex/gic_splfuncs.c
diff -u /dev/null src/sys/arch/arm/cortex/gic_splfuncs.c:1.1
--- /dev/null	Tue Aug 10 15:33:09 2021
+++ src/sys/arch/arm/cortex/gic_splfuncs.c	Tue Aug 10 15:33:09 2021
@@ -0,0 +1,107 @@
+/* $NetBSD: gic_splfuncs.c,v 1.1 2021/08/10 15:33:09 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: gic_splfuncs.c,v 1.1 2021/08/10 15:33:09 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/atomic.h>
+#include <sys/kernel.h>
+#include <sys/lwp.h>
+
+#include <arm/pic/picvar.h>
+#include <arm/cpu.h>
+#include <arm/cpufunc.h>
+#include <arm/locore.h>
+
+#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;
+}
+
+static int
+gic_spllower(int newipl)
+{
+	struct cpu_info * const ci = curcpu();
+	const int oldipl = ci->ci_cpl;
+	KASSERT(panicstr || newipl <= ci->ci_cpl);
+	if (newipl < ci->ci_cpl) {
+		register_t psw = DISABLE_INTERRUPT_SAVE();
+		ci->ci_intr_depth++;
+		pic_do_pending_ints(psw, newipl, NULL);
+		ci->ci_intr_depth--;
+		if ((psw & I32_bit) == 0 || newipl == IPL_NONE) {
+			ENABLE_INTERRUPT();
+		}
+		cpu_dosoftints();
+	}
+
+	return oldipl;
+}
+
+static void
+gic_splx(int newipl)
+{
+	struct cpu_info * const ci = curcpu();
+
+	if (newipl >= ci->ci_cpl) {
+		return;
+	}
+
+	if (ci->ci_hwpl <= newipl) {
+		ci->ci_cpl = newipl;
+		if (ci->ci_hwpl <= newipl) {
+			return;
+		}
+	}
+
+	register_t psw = DISABLE_INTERRUPT_SAVE();
+	ci->ci_intr_depth++;
+	pic_do_pending_ints(psw, newipl, NULL);
+	ci->ci_intr_depth--;
+	if ((psw & I32_bit) == 0) {
+		ENABLE_INTERRUPT();
+	}
+	cpu_dosoftints();
+}
+
+void
+gic_spl_init(void)
+{
+	_splraise = gic_splraise;
+	_spllower = gic_spllower;
+	splx = gic_splx;
+}
Index: src/sys/arch/arm/cortex/gic_splfuncs.h
diff -u /dev/null src/sys/arch/arm/cortex/gic_splfuncs.h:1.1
--- /dev/null	Tue Aug 10 15:33:09 2021
+++ src/sys/arch/arm/cortex/gic_splfuncs.h	Tue Aug 10 15:33:09 2021
@@ -0,0 +1,34 @@
+/* $NetBSD: gic_splfuncs.h,v 1.1 2021/08/10 15:33:09 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.
+ */
+
+#ifndef _ARM_GIC_SPLFUNCS_H
+#define _ARM_GIC_SPLFUNCS_H
+
+void	gic_spl_init(void);
+
+#endif /* !_ARM_GIC_SPLFUNCS_H */

Reply via email to