-/* $OpenBSD: ampintc.c,v 1.7 2017/02/25 17:04:19 patrick Exp $ */
+/* $OpenBSD: ampintc.c,v 1.8 2017/04/08 22:31:33 kettenis Exp $ */
/*
* Copyright (c) 2007,2009,2011 Dale Rahn <drahn@openbsd.org>
*
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;
};
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
{
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;
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", 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++) {
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);
}
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);
}