diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c --- a/sys/kern/subr_intr.c +++ b/sys/kern/subr_intr.c @@ -151,8 +151,8 @@ u_long *ii_count; }; -static device_t intr_ipi_dev; -static u_int intr_ipi_dev_priority; +static device_t intr_ipi_dev[INTR_IPI_COUNT]; +static u_int intr_ipi_dev_priority[INTR_IPI_COUNT]; static bool intr_ipi_dev_frozen; #endif @@ -1863,9 +1863,33 @@ return (EBUSY); } - if (intr_ipi_dev == NULL || priority > intr_ipi_dev_priority) { - intr_ipi_dev_priority = priority; - intr_ipi_dev = dev; + for (u_int ipi = 0; ipi < nitems(intr_ipi_dev); ipi++) { + if (intr_ipi_dev[ipi] == NULL || + priority > intr_ipi_dev_priority[ipi]) { + intr_ipi_dev_priority[ipi] = priority; + intr_ipi_dev[ipi] = dev; + } + } + + return (0); +} + +int +intr_ipi_pic_register_ipi(u_int ipi, device_t dev, u_int priority) +{ + if (intr_ipi_dev_frozen) { + device_printf(dev, "IPI device already frozen"); + return (EBUSY); + } + + if (ipi >= nitems(intr_ipi_dev)) { + device_printf(dev, "Invalid IPI: %u\n", ipi); + return (EINVAL); + } + if (intr_ipi_dev[ipi] == NULL || + priority > intr_ipi_dev_priority[ipi]) { + intr_ipi_dev_priority[ipi] = priority; + intr_ipi_dev[ipi] = dev; } return (0); @@ -1884,17 +1908,19 @@ struct intr_ipi *ii; int error; + if (ipi >= nitems(intr_ipi_dev)) + panic("%s: invalid IPI: %u\n", __func__, ipi); if (!intr_ipi_dev_frozen) { - if (intr_ipi_dev == NULL) + if (intr_ipi_dev[ipi] == NULL) panic("%s: no IPI PIC attached", __func__); intr_ipi_dev_frozen = true; - device_printf(intr_ipi_dev, "using for IPIs\n"); + device_printf(intr_ipi_dev[ipi], "using for IPIs\n"); } KASSERT(hand != NULL, ("%s: ipi %u no handler", __func__, ipi)); - error = PIC_IPI_SETUP(intr_ipi_dev, ipi, &isrc); + error = PIC_IPI_SETUP(intr_ipi_dev[ipi], ipi, &isrc); if (error != 0) return; @@ -1909,7 +1935,7 @@ strlcpy(ii->ii_name, name, INTR_IPI_NAMELEN); ii->ii_count = intr_ipi_setup_counters(name); - PIC_ENABLE_INTR(intr_ipi_dev, isrc); + PIC_ENABLE_INTR(intr_ipi_dev[ipi], isrc); } void @@ -1920,6 +1946,9 @@ KASSERT(intr_ipi_dev_frozen, ("%s: IPI device not yet frozen", __func__)); + if (ipi >= nitems(intr_ipi_dev)) + panic("%s: invalid IPI: %u\n", __func__, ipi); + ii = intr_ipi_lookup(ipi); if (ii->ii_count == NULL) panic("%s: not setup IPI %u", __func__, ipi); @@ -1937,7 +1966,7 @@ dsb(ishst); #endif - PIC_IPI_SEND(intr_ipi_dev, ii->ii_isrc, cpus, ipi); + PIC_IPI_SEND(intr_ipi_dev[ipi], ii->ii_isrc, cpus, ipi); } /* diff --git a/sys/sys/intr.h b/sys/sys/intr.h --- a/sys/sys/intr.h +++ b/sys/sys/intr.h @@ -163,6 +163,7 @@ typedef void intr_ipi_handler_t(void *); int intr_ipi_pic_register(device_t dev, u_int priority); +int intr_ipi_pic_register_ipi(u_int ipi, device_t dev, u_int priority); void intr_ipi_setup(u_int ipi, const char *name, intr_ipi_handler_t *hand, void *arg); void intr_ipi_send(cpuset_t cpus, u_int ipi);