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);
 }
 

Reply via email to