This brings the arm64 code back in line with the armv7 code. Can't easily test this myself right now so I would appreciate it if somebody could try this on a pine64 or one of the amd boards.
ok? Index: arch/arm64/dev/ampintc.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/dev/ampintc.c,v retrieving revision 1.7 diff -u -p -r1.7 ampintc.c --- arch/arm64/dev/ampintc.c 25 Feb 2017 17:04:19 -0000 1.7 +++ arch/arm64/dev/ampintc.c 21 Mar 2017 22:05:07 -0000 @@ -138,6 +138,7 @@ struct ampintc_softc { int sc_nintr; bus_space_tag_t sc_iot; bus_space_handle_t sc_d_ioh, sc_p_ioh; + uint8_t sc_cpu_mask[ICD_ICTR_CPU_M + 1]; struct evcount sc_spur; struct interrupt_controller sc_ic; }; @@ -184,7 +185,7 @@ void ampintc_set_priority(int, int); void ampintc_intr_enable(int); void ampintc_intr_disable(int); void ampintc_intr_config(int, int); -void ampintc_route(int, int , int); +void ampintc_route(int, int, struct cpu_info *); struct cfattach ampintc_ca = { sizeof (struct ampintc_softc), ampintc_match, ampintc_attach @@ -220,7 +221,8 @@ ampintc_attach(struct device *parent, st { struct ampintc_softc *sc = (struct ampintc_softc *)self; struct fdt_attach_args *faa = aux; - int i, nintr; + int i, nintr, ncpu; + uint32_t ictr; ampintc = sc; @@ -240,11 +242,16 @@ ampintc_attach(struct device *parent, st evcount_attach(&sc->sc_spur, "irq1023/spur", NULL); - nintr = 32 * (bus_space_read_4(sc->sc_iot, sc->sc_d_ioh, - ICD_ICTR) & ICD_ICTR_ITL_M); + ictr = bus_space_read_4(sc->sc_iot, sc->sc_d_ioh, ICD_ICTR); + nintr = 32 * ((ictr >> ICD_ICTR_ITL_SH) & ICD_ICTR_ITL_M); nintr += 32; /* ICD_ICTR + 1, irq 0-31 is SGI, 32+ is PPI */ sc->sc_nintr = nintr; - printf(" nirq %d", nintr); + ncpu = ((ictr >> ICD_ICTR_CPU_SH) & ICD_ICTR_CPU_M) + 1; + printf(" nirq %d, ncpu %d\n", nintr, ncpu); + + KASSERT(curcpu()->ci_cpuid <= ICD_ICTR_CPU_M); + sc->sc_cpu_mask[curcpu()->ci_cpuid] = + bus_space_read_1(sc->sc_iot, sc->sc_d_ioh, ICD_IPTRn(0)); /* Disable all interrupts, clear all pending */ for (i = 0; i < nintr/32; i++) { @@ -403,11 +410,10 @@ ampintc_calc_mask(void) if (min != IPL_NONE) { ampintc_set_priority(irq, min); ampintc_intr_enable(irq); - ampintc_route(irq, IRQ_ENABLE, 0); + ampintc_route(irq, IRQ_ENABLE, ci); } else { ampintc_intr_disable(irq); - ampintc_route(irq, IRQ_DISABLE, 0); - + ampintc_route(irq, IRQ_DISABLE, ci); } } ampintc_setipl(ci->ci_cpl); @@ -476,16 +482,19 @@ ampintc_eoi(uint32_t eoi) } void -ampintc_route(int irq, int enable, int cpu) +ampintc_route(int irq, int enable, struct cpu_info *ci) { - uint8_t val; struct ampintc_softc *sc = ampintc; + uint8_t mask, val; + + KASSERT(ci->ci_cpuid <= ICD_ICTR_CPU_M); + mask = sc->sc_cpu_mask[ci->ci_cpuid]; val = bus_space_read_1(sc->sc_iot, sc->sc_d_ioh, ICD_IPTRn(irq)); if (enable == IRQ_ENABLE) - val |= (1 << cpu); + val |= mask; else - val &= ~(1 << cpu); + val &= ~mask; bus_space_write_1(sc->sc_iot, sc->sc_d_ioh, ICD_IPTRn(irq), val); }