diff --git a/sys/arch/arm/cortex/gic.c b/sys/arch/arm/cortex/gic.c index 1420331ba06..b4e230dc3ff 100644 --- a/sys/arch/arm/cortex/gic.c +++ b/sys/arch/arm/cortex/gic.c @@ -221,9 +221,29 @@ static void armgic_set_priority(struct pic_softc *pic, int ipl) { struct armgic_softc * const sc = PICTOSOFTC(pic); + struct cpu_info * const ci = curcpu(); + const uint32_t newpri = armgic_ipl_to_priority(ipl); + const uint32_t curpri = gicc_read(sc, GICC_PMR); - const uint32_t priority = armgic_ipl_to_priority(ipl); - gicc_write(sc, GICC_PMR, priority); + /* + * If an interrupt occurs between the PMR read and raising the PMR + * there is no matter as it'll return it to the same value + * + * GIC priorities with lower values block higher priority interrupts + */ + if (newpri < curpri) { + /* raising ipl */ + gicc_write(sc, GICC_PMR, newpri); + arm_dsb(); + arm_isb(); + ci->ci_cpl = ipl; + } else if (newpri >= curpri) { + /* lowering ipl */ + ci->ci_cpl = ipl; + arm_dsb(); + arm_isb(); + gicc_write(sc, GICC_PMR, newpri); + } } #ifdef __HAVE_PIC_FAST_SOFTINTS @@ -273,13 +293,7 @@ armgic_irq_handler(void *tf) if (irq == GICC_IAR_IRQ_SPURIOUS || irq == GICC_IAR_IRQ_SSPURIOUS) { - iar = gicc_read(sc, GICC_IAR); - irq = __SHIFTOUT(iar, GICC_IAR_IRQ); - if (irq == GICC_IAR_IRQ_SPURIOUS) - break; - if (irq == GICC_IAR_IRQ_SSPURIOUS) { - break; - } + break; } //const uint32_t cpuid = __SHIFTOUT(iar, GICC_IAR_CPUID_MASK); @@ -303,10 +317,13 @@ armgic_irq_handler(void *tf) pic_do_pending_ints(I32_bit, ipl, tf); KASSERT(ci->ci_cpl == ipl); } else { - KASSERTMSG(ipl > ci->ci_cpl, "ipl %d cpl %d hw-ipl %#x", - ipl, ci->ci_cpl, - gicc_read(sc, GICC_PMR)); +// KASSERTMSG(ipl >= ci->ci_cpl, "ipl %d cpl %d hw-ipl %#x", +// ipl, ci->ci_cpl, +// gicc_read(sc, GICC_PMR)); + /* raising ipl */ gicc_write(sc, GICC_PMR, armgic_ipl_to_priority(ipl)); + arm_dsb(); + arm_isb(); ci->ci_cpl = ipl; } cpsie(I32_bit); diff --git a/sys/arch/arm/cortex/gtmr.c b/sys/arch/arm/cortex/gtmr.c index ae8fcb4b97f..edfd92a22f5 100644 --- a/sys/arch/arm/cortex/gtmr.c +++ b/sys/arch/arm/cortex/gtmr.c @@ -48,7 +48,6 @@ __KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.23 2017/11/30 14:50:34 skrll Exp $"); #include #include - #include static int gtmr_match(device_t, cfdata_t, void *); diff --git a/sys/arch/arm/pic/pic.c b/sys/arch/arm/pic/pic.c index 73ea271a7a5..22e4abefea3 100644 --- a/sys/arch/arm/pic/pic.c +++ b/sys/arch/arm/pic/pic.c @@ -108,12 +108,10 @@ static int pic_init(void); void pic_set_priority(struct cpu_info *ci, int newipl) { - register_t psw = cpsid(I32_bit); - if (pic_list[0] != NULL) - (pic_list[0]->pic_ops->pic_set_priority)(pic_list[0], newipl); - ci->ci_cpl = newipl; - if ((psw & I32_bit) == 0) - cpsie(I32_bit); + struct pic_softc *pic = pic_list[0]; + + if (pic && pic->pic_ops->pic_set_priority) + (pic->pic_ops->pic_set_priority)(pic, newipl); } #endif