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 */