Module Name:    src
Committed By:   jmcneill
Date:           Thu Sep  5 13:33:11 UTC 2019

Modified Files:
        src/sys/arch/arm/cortex: gicv3.c

Log Message:
- Use pic_do_pending_ints in intr handler
- Sprinkle isb
- Fix PMR bits detection on eMAG, from OpenBSD


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 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/gicv3.c
diff -u src/sys/arch/arm/cortex/gicv3.c:1.20 src/sys/arch/arm/cortex/gicv3.c:1.21
--- src/sys/arch/arm/cortex/gicv3.c:1.20	Sun Jun 30 11:11:38 2019
+++ src/sys/arch/arm/cortex/gicv3.c	Thu Sep  5 13:33:11 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: gicv3.c,v 1.20 2019/06/30 11:11:38 jmcneill Exp $ */
+/* $NetBSD: gicv3.c,v 1.21 2019/09/05 13:33:11 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.20 2019/06/30 11:11:38 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gicv3.c,v 1.21 2019/09/05 13:33:11 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -213,6 +213,7 @@ gicv3_set_priority(struct pic_softc *pic
 	struct gicv3_softc * const sc = PICTOSOFTC(pic);
 
 	icc_pmr_write(IPL_TO_PMR(sc, ipl));
+	arm_isb();
 }
 
 static void
@@ -437,14 +438,17 @@ gicv3_ipi_send(struct pic_softc *pic, co
 			if ((ci->ci_gic_sgir & ICC_SGIR_EL1_Aff) != aff) {
 				if (targets != 0) {
 					icc_sgi1r_write(intid | aff | targets);
+					arm_isb();
 					targets = 0;
 				}
 				aff = (ci->ci_gic_sgir & ICC_SGIR_EL1_Aff);
 			}
 			targets |= (ci->ci_gic_sgir & ICC_SGIR_EL1_TargetList);
 		}
-		if (targets != 0)
+		if (targets != 0) {
 			icc_sgi1r_write(intid | aff | targets);
+			arm_isb();
+		}
 	}
 }
 
@@ -715,6 +719,7 @@ gicv3_irq_handler(void *frame)
 
 	for (;;) {
 		const uint32_t iar = icc_iar1_read();
+		arm_dsb();
 		const uint32_t irq = __SHIFTOUT(iar, ICC_IAR_INTID);
 		if (irq == ICC_IAR_INTID_SPURIOUS)
 			break;
@@ -726,26 +731,39 @@ gicv3_irq_handler(void *frame)
 		struct intrsource * const is = pic->pic_sources[irq - pic->pic_irqbase];
 		KASSERT(is != NULL);
 
+		const bool early_eoi = irq < GIC_LPI_BASE && is->is_type == IST_EDGE;
+
 		const int ipl = is->is_ipl;
-		if (ci->ci_cpl < ipl)
-			pic_set_priority(ci, ipl);
+		if (__predict_false(ipl < ci->ci_cpl)) {
+			pic_do_pending_ints(I32_bit, ipl, frame);
+		} else {
+			gicv3_set_priority(pic, ipl);
+			ci->ci_cpl = ipl;
+		}
+
+		if (early_eoi) {
+			icc_eoi1r_write(iar);
+			arm_isb();
+		}
 
 		cpsie(I32_bit);
 		pic_dispatch(is, frame);
 		cpsid(I32_bit);
 
-		icc_eoi1r_write(iar);
+		if (!early_eoi) {
+			icc_eoi1r_write(iar);
+			arm_isb();
+		}
 	}
 
-	if (ci->ci_cpl != oldipl)
-		pic_set_priority(ci, oldipl);
+	pic_do_pending_ints(I32_bit, oldipl, frame);
 }
 
 static int
 gicv3_detect_pmr_bits(struct gicv3_softc *sc)
 {
 	const uint32_t opmr = icc_pmr_read();
-	icc_pmr_write(0xff);
+	icc_pmr_write(0xbf);
 	const uint32_t npmr = icc_pmr_read();
 	icc_pmr_write(opmr);
 

Reply via email to