Wed Jun 12 10:02:17 2019 UTC ()
Adjust priority mappings, NFCI


(jmcneill)
diff -r1.13 -r1.14 src/sys/arch/arm/cortex/gicv3.c

cvs diff -r1.13 -r1.14 src/sys/arch/arm/cortex/gicv3.c (expand / switch to unified diff)

--- src/sys/arch/arm/cortex/gicv3.c 2018/11/23 11:49:04 1.13
+++ src/sys/arch/arm/cortex/gicv3.c 2019/06/12 10:02:17 1.14
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: gicv3.c,v 1.13 2018/11/23 11:49:04 jmcneill Exp $ */ 1/* $NetBSD: gicv3.c,v 1.14 2019/06/12 10:02:17 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include "opt_multiprocessor.h" 29#include "opt_multiprocessor.h"
30 30
31#define _INTR_PRIVATE 31#define _INTR_PRIVATE
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.13 2018/11/23 11:49:04 jmcneill Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.14 2019/06/12 10:02:17 jmcneill Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/bus.h> 38#include <sys/bus.h>
39#include <sys/device.h> 39#include <sys/device.h>
40#include <sys/intr.h> 40#include <sys/intr.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/cpu.h> 42#include <sys/cpu.h>
43 43
44#include <arm/locore.h> 44#include <arm/locore.h>
45#include <arm/armreg.h> 45#include <arm/armreg.h>
46 46
47#include <arm/cortex/gicv3.h> 47#include <arm/cortex/gicv3.h>
@@ -145,27 +145,27 @@ gicv3_block_irqs(struct pic_softc *pic,  @@ -145,27 +145,27 @@ gicv3_block_irqs(struct pic_softc *pic,
145 ; 145 ;
146 } 146 }
147} 147}
148 148
149static void 149static void
150gicv3_establish_irq(struct pic_softc *pic, struct intrsource *is) 150gicv3_establish_irq(struct pic_softc *pic, struct intrsource *is)
151{ 151{
152 struct gicv3_softc * const sc = PICTOSOFTC(pic); 152 struct gicv3_softc * const sc = PICTOSOFTC(pic);
153 const u_int group = is->is_irq / 32; 153 const u_int group = is->is_irq / 32;
154 uint32_t ipriority, icfg; 154 uint32_t ipriority, icfg;
155 uint64_t irouter; 155 uint64_t irouter;
156 u_int n; 156 u_int n;
157 157
158 const u_int ipriority_val = 0x80 | IPL_TO_PRIORITY(is->is_ipl); 158 const u_int ipriority_val = 0x80 | (IPL_TO_PRIORITY(is->is_ipl) >> 1);
159 const u_int ipriority_shift = (is->is_irq & 0x3) * 8; 159 const u_int ipriority_shift = (is->is_irq & 0x3) * 8;
160 const u_int icfg_shift = (is->is_irq & 0xf) * 2; 160 const u_int icfg_shift = (is->is_irq & 0xf) * 2;
161 161
162 if (group == 0) { 162 if (group == 0) {
163 /* SGIs and PPIs are always MP-safe */ 163 /* SGIs and PPIs are always MP-safe */
164 is->is_mpsafe = true; 164 is->is_mpsafe = true;
165 165
166 /* Update interrupt configuration and priority on all redistributors */ 166 /* Update interrupt configuration and priority on all redistributors */
167 for (n = 0; n < sc->sc_bsh_r_count; n++) { 167 for (n = 0; n < sc->sc_bsh_r_count; n++) {
168 icfg = gicr_read_4(sc, n, GICR_ICFGRn(is->is_irq / 16)); 168 icfg = gicr_read_4(sc, n, GICR_ICFGRn(is->is_irq / 16));
169 if (is->is_type == IST_LEVEL) 169 if (is->is_type == IST_LEVEL)
170 icfg &= ~(0x2 << icfg_shift); 170 icfg &= ~(0x2 << icfg_shift);
171 if (is->is_type == IST_EDGE) 171 if (is->is_type == IST_EDGE)
@@ -196,27 +196,27 @@ gicv3_establish_irq(struct pic_softc *pi @@ -196,27 +196,27 @@ gicv3_establish_irq(struct pic_softc *pi
196 gicd_write_4(sc, GICD_ICFGRn(is->is_irq / 16), icfg); 196 gicd_write_4(sc, GICD_ICFGRn(is->is_irq / 16), icfg);
197 197
198 /* Update interrupt priority */ 198 /* Update interrupt priority */
199 ipriority = gicd_read_4(sc, GICD_IPRIORITYRn(is->is_irq / 4)); 199 ipriority = gicd_read_4(sc, GICD_IPRIORITYRn(is->is_irq / 4));
200 ipriority &= ~(0xff << ipriority_shift); 200 ipriority &= ~(0xff << ipriority_shift);
201 ipriority |= (ipriority_val << ipriority_shift); 201 ipriority |= (ipriority_val << ipriority_shift);
202 gicd_write_4(sc, GICD_IPRIORITYRn(is->is_irq / 4), ipriority); 202 gicd_write_4(sc, GICD_IPRIORITYRn(is->is_irq / 4), ipriority);
203 } 203 }
204} 204}
205 205
206static void 206static void
207gicv3_set_priority(struct pic_softc *pic, int ipl) 207gicv3_set_priority(struct pic_softc *pic, int ipl)
208{ 208{
209 icc_pmr_write(IPL_TO_PRIORITY(ipl) << 1); 209 icc_pmr_write(IPL_TO_PRIORITY(ipl));
210} 210}
211 211
212static void 212static void
213gicv3_dist_enable(struct gicv3_softc *sc) 213gicv3_dist_enable(struct gicv3_softc *sc)
214{ 214{
215 uint32_t gicd_ctrl; 215 uint32_t gicd_ctrl;
216 u_int n; 216 u_int n;
217 217
218 /* Disable the distributor */ 218 /* Disable the distributor */
219 gicd_write_4(sc, GICD_CTRL, 0); 219 gicd_write_4(sc, GICD_CTRL, 0);
220 220
221 /* Wait for register write to complete */ 221 /* Wait for register write to complete */
222 while (gicd_read_4(sc, GICD_CTRL) & GICD_CTRL_RWP) 222 while (gicd_read_4(sc, GICD_CTRL) & GICD_CTRL_RWP)
@@ -261,27 +261,27 @@ gicv3_redist_enable(struct gicv3_softc * @@ -261,27 +261,27 @@ gicv3_redist_enable(struct gicv3_softc *
261 /* Wait for register write to complete */ 261 /* Wait for register write to complete */
262 while (gicr_read_4(sc, ci->ci_gic_redist, GICR_CTLR) & GICR_CTLR_RWP) 262 while (gicr_read_4(sc, ci->ci_gic_redist, GICR_CTLR) & GICR_CTLR_RWP)
263 ; 263 ;
264 264
265 /* Set default priorities */ 265 /* Set default priorities */
266 for (n = 0; n < 32; n += 4) { 266 for (n = 0; n < 32; n += 4) {
267 uint32_t priority = 0; 267 uint32_t priority = 0;
268 size_t byte_shift = 0; 268 size_t byte_shift = 0;
269 for (o = 0; o < 4; o++, byte_shift += 8) { 269 for (o = 0; o < 4; o++, byte_shift += 8) {
270 struct intrsource * const is = sc->sc_pic.pic_sources[n + o]; 270 struct intrsource * const is = sc->sc_pic.pic_sources[n + o];
271 if (is == NULL) 271 if (is == NULL)
272 priority |= 0xff << byte_shift; 272 priority |= 0xff << byte_shift;
273 else { 273 else {
274 const u_int ipriority_val = 0x80 | IPL_TO_PRIORITY(is->is_ipl); 274 const u_int ipriority_val = 0x80 | (IPL_TO_PRIORITY(is->is_ipl) >> 1);
275 priority |= ipriority_val << byte_shift; 275 priority |= ipriority_val << byte_shift;
276 } 276 }
277 } 277 }
278 gicr_write_4(sc, ci->ci_gic_redist, GICR_IPRIORITYRn(n / 4), priority); 278 gicr_write_4(sc, ci->ci_gic_redist, GICR_IPRIORITYRn(n / 4), priority);
279 } 279 }
280 280
281 /* Set all interrupts to G1NS */ 281 /* Set all interrupts to G1NS */
282 gicr_write_4(sc, ci->ci_gic_redist, GICR_IGROUPR0, ~0); 282 gicr_write_4(sc, ci->ci_gic_redist, GICR_IGROUPR0, ~0);
283 gicr_write_4(sc, ci->ci_gic_redist, GICR_IGRPMODR0, 0); 283 gicr_write_4(sc, ci->ci_gic_redist, GICR_IGRPMODR0, 0);
284 284
285 /* Restore PPI configs */ 285 /* Restore PPI configs */
286 for (n = 0, icfg = 0; n < 16; n++) { 286 for (n = 0, icfg = 0; n < 16; n++) {
287 struct intrsource * const is = sc->sc_pic.pic_sources[16 + n]; 287 struct intrsource * const is = sc->sc_pic.pic_sources[16 + n];
@@ -535,27 +535,27 @@ gicv3_lpi_block_irqs(struct pic_softc *p @@ -535,27 +535,27 @@ gicv3_lpi_block_irqs(struct pic_softc *p
535 while ((bit = ffs(mask)) != 0) { 535 while ((bit = ffs(mask)) != 0) {
536 sc->sc_lpiconf.base[irqbase + bit - 1] &= ~GIC_LPICONF_Enable; 536 sc->sc_lpiconf.base[irqbase + bit - 1] &= ~GIC_LPICONF_Enable;
537 mask &= ~__BIT(bit - 1); 537 mask &= ~__BIT(bit - 1);
538 } 538 }
539 539
540 bus_dmamap_sync(sc->sc_dmat, sc->sc_lpiconf.map, irqbase, 32, BUS_DMASYNC_PREWRITE); 540 bus_dmamap_sync(sc->sc_dmat, sc->sc_lpiconf.map, irqbase, 32, BUS_DMASYNC_PREWRITE);
541} 541}
542 542
543static void 543static void
544gicv3_lpi_establish_irq(struct pic_softc *pic, struct intrsource *is) 544gicv3_lpi_establish_irq(struct pic_softc *pic, struct intrsource *is)
545{ 545{
546 struct gicv3_softc * const sc = LPITOSOFTC(pic); 546 struct gicv3_softc * const sc = LPITOSOFTC(pic);
547 547
548 sc->sc_lpiconf.base[is->is_irq] = 0x80 | IPL_TO_PRIORITY(is->is_ipl) | GIC_LPICONF_Res1; 548 sc->sc_lpiconf.base[is->is_irq] = 0x80 | (IPL_TO_PRIORITY(is->is_ipl) >> 1) | GIC_LPICONF_Res1;
549 549
550 bus_dmamap_sync(sc->sc_dmat, sc->sc_lpiconf.map, is->is_irq, 1, BUS_DMASYNC_PREWRITE); 550 bus_dmamap_sync(sc->sc_dmat, sc->sc_lpiconf.map, is->is_irq, 1, BUS_DMASYNC_PREWRITE);
551} 551}
552 552
553static void 553static void
554gicv3_lpi_cpu_init(struct pic_softc *pic, struct cpu_info *ci) 554gicv3_lpi_cpu_init(struct pic_softc *pic, struct cpu_info *ci)
555{ 555{
556 struct gicv3_softc * const sc = LPITOSOFTC(pic); 556 struct gicv3_softc * const sc = LPITOSOFTC(pic);
557 struct gicv3_lpi_callback *cb; 557 struct gicv3_lpi_callback *cb;
558 uint32_t ctlr; 558 uint32_t ctlr;
559 559
560 /* If physical LPIs are not supported on this redistributor, just return. */ 560 /* If physical LPIs are not supported on this redistributor, just return. */
561 const uint64_t typer = gicr_read_8(sc, ci->ci_gic_redist, GICR_TYPER); 561 const uint64_t typer = gicr_read_8(sc, ci->ci_gic_redist, GICR_TYPER);