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