Index: agintc.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/dev/agintc.c,v diff -u -p -r1.62 agintc.c --- agintc.c 24 Jan 2025 20:17:28 -0000 1.62 +++ agintc.c 4 Jul 2025 23:53:08 -0000 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -182,9 +183,9 @@ struct agintc_softc { struct agintc_dmamem *sc_prop; struct agintc_dmamem *sc_pend; struct interrupt_controller sc_ic; - int sc_ipi_num[3]; /* id for each ipi */ + int sc_ipi_num; /* id for ipi */ int sc_ipi_reason[MAXCPUS]; /* cause of ipi */ - void *sc_ipi_irq[3]; /* irqhandle for each ipi */ + void *sc_ipi_irq; /* ipi irqhandle */ }; struct agintc_softc *agintc_sc; @@ -260,8 +261,7 @@ void agintc_r_wait_rwp(struct agintc_so int agintc_ipi_ddb(void *v); int agintc_ipi_halt(void *v); -int agintc_ipi_nop(void *v); -int agintc_ipi_combined(void *); +int agintc_ipi_handler(void *); void agintc_send_ipi(struct cpu_info *, int); void agintc_msi_discard(struct agintc_lpi_info *); @@ -317,7 +317,7 @@ agintc_attach(struct device *parent, str int i, nbits, nintr; int idx, offset, nredist; #ifdef MULTIPROCESSOR - int nipi, ipiirq[3]; + int ipiirq; #endif psw = intr_disable(); @@ -600,13 +600,7 @@ agintc_attach(struct device *parent, str #ifdef MULTIPROCESSOR /* setup IPI interrupts */ - /* - * Ideally we want three IPI interrupts, one for NOP, one for - * DDB and one for HALT. However we can survive if only one - * is available; it is possible that most are not available to - * the non-secure OS. - */ - nipi = 0; + ipiirq = -1; for (i = 0; i < 16; i++) { int hwcpu = sc->sc_cpuremap[cpu_number()]; int reg, oldreg; @@ -625,56 +619,19 @@ agintc_attach(struct device *parent, str /* return to original value, will be set when used */ bus_space_write_1(sc->sc_iot, sc->sc_r_ioh[hwcpu], GICR_IPRIORITYR(i), oldreg); - - if (nipi == 0) - printf(" ipi: %d", i); - else - printf(", %d", i); - ipiirq[nipi++] = i; - if (nipi == 3) - break; + ipiirq = i; + break; } - if (nipi == 0) + if (ipiirq == -1) panic("no irq available for IPI"); - switch (nipi) { - case 1: - sc->sc_ipi_irq[0] = agintc_intr_establish(ipiirq[0], - IST_EDGE_RISING, IPL_IPI|IPL_MPSAFE, NULL, - agintc_ipi_combined, sc, "ipi"); - sc->sc_ipi_num[ARM_IPI_NOP] = ipiirq[0]; - sc->sc_ipi_num[ARM_IPI_DDB] = ipiirq[0]; - sc->sc_ipi_num[ARM_IPI_HALT] = ipiirq[0]; - break; - case 2: - sc->sc_ipi_irq[0] = agintc_intr_establish(ipiirq[0], - IST_EDGE_RISING, IPL_IPI|IPL_MPSAFE, NULL, - agintc_ipi_nop, sc, "ipinop"); - sc->sc_ipi_num[ARM_IPI_NOP] = ipiirq[0]; - sc->sc_ipi_irq[1] = agintc_intr_establish(ipiirq[1], - IST_EDGE_RISING, IPL_IPI|IPL_MPSAFE, NULL, - agintc_ipi_combined, sc, "ipi"); - sc->sc_ipi_num[ARM_IPI_DDB] = ipiirq[1]; - sc->sc_ipi_num[ARM_IPI_HALT] = ipiirq[1]; - break; - case 3: - sc->sc_ipi_irq[0] = agintc_intr_establish(ipiirq[0], - IST_EDGE_RISING, IPL_IPI|IPL_MPSAFE, NULL, - agintc_ipi_nop, sc, "ipinop"); - sc->sc_ipi_num[ARM_IPI_NOP] = ipiirq[0]; - sc->sc_ipi_irq[1] = agintc_intr_establish(ipiirq[1], - IST_EDGE_RISING, IPL_IPI|IPL_MPSAFE, NULL, - agintc_ipi_ddb, sc, "ipiddb"); - sc->sc_ipi_num[ARM_IPI_DDB] = ipiirq[1]; - sc->sc_ipi_irq[2] = agintc_intr_establish(ipiirq[2], - IST_EDGE_RISING, IPL_IPI|IPL_MPSAFE, NULL, - agintc_ipi_halt, sc, "ipihalt"); - sc->sc_ipi_num[ARM_IPI_HALT] = ipiirq[2]; - break; - default: - panic("nipi unexpected number %d", nipi); - } + printf(" ipi %d", ipiirq); + + sc->sc_ipi_irq = agintc_intr_establish(ipiirq, + IST_EDGE_RISING, IPL_IPI|IPL_MPSAFE, NULL, + agintc_ipi_handler, sc, "ipi"); + sc->sc_ipi_num = ipiirq; intr_send_ipi_func = agintc_send_ipi; #endif @@ -798,12 +755,8 @@ agintc_cpuinit(void) bus_space_write_4(sc->sc_iot, sc->sc_r_ioh[hwcpu], GICR_IGRPMODR0, 0); - if (sc->sc_ipi_irq[0] != NULL) - agintc_route_irq(sc->sc_ipi_irq[0], IRQ_ENABLE, curcpu()); - if (sc->sc_ipi_irq[1] != NULL) - agintc_route_irq(sc->sc_ipi_irq[1], IRQ_ENABLE, curcpu()); - if (sc->sc_ipi_irq[2] != NULL) - agintc_route_irq(sc->sc_ipi_irq[2], IRQ_ENABLE, curcpu()); + if (sc->sc_ipi_irq != NULL) + agintc_route_irq(sc->sc_ipi_irq, IRQ_ENABLE, curcpu()); __asm volatile("msr "STR(ICC_PMR)", %x0" :: "r"(0xff)); __asm volatile("msr "STR(ICC_BPR1)", %x0" :: "r"(0)); @@ -1451,7 +1404,7 @@ agintc_ipi_halt(void *v) int old = curcpu()->ci_cpl; intr_disable(); - agintc_eoi(sc->sc_ipi_num[ARM_IPI_HALT]); + agintc_eoi(sc->sc_ipi_num); agintc_setipl(IPL_NONE); cpu_halt(); @@ -1462,47 +1415,44 @@ agintc_ipi_halt(void *v) } int -agintc_ipi_nop(void *v) -{ - /* Nothing to do here, just enough to wake up from WFI */ - return 1; -} - -int -agintc_ipi_combined(void *v) +agintc_ipi_handler(void *v) { struct agintc_softc *sc = v; + struct cpu_info *ci = curcpu(); + u_int reasons; - if (sc->sc_ipi_reason[cpu_number()] == ARM_IPI_DDB) { - sc->sc_ipi_reason[cpu_number()] = ARM_IPI_NOP; - return agintc_ipi_ddb(v); - } else if (sc->sc_ipi_reason[cpu_number()] == ARM_IPI_HALT) { - sc->sc_ipi_reason[cpu_number()] = ARM_IPI_NOP; - return agintc_ipi_halt(v); - } else { - return agintc_ipi_nop(v); + reasons = sc->sc_ipi_reason[ci->ci_cpuid]; + if (reasons) { + reasons = atomic_swap_uint(&sc->sc_ipi_reason[ci->ci_cpuid], 0); + if (ISSET(reasons, 1 << ARM_IPI_DDB)) + agintc_ipi_ddb(v); + if (ISSET(reasons, 1 << ARM_IPI_HALT)) + agintc_ipi_halt(v); } + + return (1); } void -agintc_send_ipi(struct cpu_info *ci, int id) +agintc_send_ipi(struct cpu_info *ci, int reason) { struct agintc_softc *sc = agintc_sc; uint64_t sendmask; - if (ci == curcpu() && id == ARM_IPI_NOP) - return; - - /* never overwrite IPI_DDB or IPI_HALT with IPI_NOP */ - if (id == ARM_IPI_DDB || id == ARM_IPI_HALT) - sc->sc_ipi_reason[ci->ci_cpuid] = id; + if (reason == ARM_IPI_NOP) { + if (ci == curcpu()) + return; + } else { + atomic_setbits_int(&sc->sc_ipi_reason[ci->ci_cpuid], + 1 << reason); + } /* will only send 1 cpu */ sendmask = (ci->ci_mpidr & MPIDR_AFF3) << 16; sendmask |= (ci->ci_mpidr & MPIDR_AFF2) << 16; sendmask |= (ci->ci_mpidr & MPIDR_AFF1) << 8; sendmask |= 1 << (ci->ci_mpidr & 0x0f); - sendmask |= (sc->sc_ipi_num[id] << 24); + sendmask |= (sc->sc_ipi_num << 24); __asm volatile ("msr " STR(ICC_SGI1R)", %x0" ::"r"(sendmask)); } Index: ampintc.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/dev/ampintc.c,v diff -u -p -r1.32 ampintc.c --- ampintc.c 6 Jul 2024 10:39:50 -0000 1.32 +++ ampintc.c 4 Jul 2025 23:53:08 -0000 @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -142,7 +143,7 @@ struct ampintc_softc { struct evcount sc_spur; struct interrupt_controller sc_ic; int sc_ipi_reason[ICD_ICTR_CPU_M + 1]; - int sc_ipi_num[3]; + int sc_ipi_num; }; struct ampintc_softc *ampintc; @@ -195,8 +196,7 @@ void ampintc_route(int, int, struct cp void ampintc_route_irq(void *, int, struct cpu_info *); void ampintc_intr_barrier(void *); -int ampintc_ipi_combined(void *); -int ampintc_ipi_nop(void *); +int ampintc_ipi_handler(void *); int ampintc_ipi_ddb(void *); int ampintc_ipi_halt(void *); void ampintc_send_ipi(struct cpu_info *, int); @@ -239,7 +239,7 @@ ampintc_attach(struct device *parent, st int i, nintr, ncpu; uint32_t ictr; #ifdef MULTIPROCESSOR - int nipi, ipiirq[3]; + int ipiirq; #endif ampintc = sc; @@ -294,13 +294,7 @@ ampintc_attach(struct device *parent, st #ifdef MULTIPROCESSOR /* setup IPI interrupts */ - /* - * Ideally we want three IPI interrupts, one for NOP, one for - * DDB and one for HALT. However we can survive if only one - * is available; it is possible that most are not available to - * the non-secure OS. - */ - nipi = 0; + ipiirq = -1; for (i = 0; i < 16; i++) { int reg, oldreg; @@ -318,49 +312,18 @@ ampintc_attach(struct device *parent, st bus_space_write_1(sc->sc_iot, sc->sc_d_ioh, ICD_IPRn(i), oldreg); - if (nipi == 0) - printf(" ipi: %d", i); - else - printf(", %d", i); - ipiirq[nipi++] = i; - if (nipi == 3) - break; + ipiirq = i; + break; } - if (nipi == 0) + if (ipiirq == -1) panic ("no irq available for IPI"); - switch (nipi) { - case 1: - ampintc_intr_establish(ipiirq[0], IST_EDGE_RISING, - IPL_IPI|IPL_MPSAFE, NULL, ampintc_ipi_combined, sc, "ipi"); - sc->sc_ipi_num[ARM_IPI_NOP] = ipiirq[0]; - sc->sc_ipi_num[ARM_IPI_DDB] = ipiirq[0]; - sc->sc_ipi_num[ARM_IPI_HALT] = ipiirq[0]; - break; - case 2: - ampintc_intr_establish(ipiirq[0], IST_EDGE_RISING, - IPL_IPI|IPL_MPSAFE, NULL, ampintc_ipi_nop, sc, "ipinop"); - sc->sc_ipi_num[ARM_IPI_NOP] = ipiirq[0]; - ampintc_intr_establish(ipiirq[1], IST_EDGE_RISING, - IPL_IPI|IPL_MPSAFE, NULL, ampintc_ipi_combined, sc, "ipi"); - sc->sc_ipi_num[ARM_IPI_DDB] = ipiirq[1]; - sc->sc_ipi_num[ARM_IPI_HALT] = ipiirq[1]; - break; - case 3: - ampintc_intr_establish(ipiirq[0], IST_EDGE_RISING, - IPL_IPI|IPL_MPSAFE, NULL, ampintc_ipi_nop, sc, "ipinop"); - sc->sc_ipi_num[ARM_IPI_NOP] = ipiirq[0]; - ampintc_intr_establish(ipiirq[1], IST_EDGE_RISING, - IPL_IPI|IPL_MPSAFE, NULL, ampintc_ipi_ddb, sc, "ipiddb"); - sc->sc_ipi_num[ARM_IPI_DDB] = ipiirq[1]; - ampintc_intr_establish(ipiirq[2], IST_EDGE_RISING, - IPL_IPI|IPL_MPSAFE, NULL, ampintc_ipi_halt, sc, "ipihalt"); - sc->sc_ipi_num[ARM_IPI_HALT] = ipiirq[2]; - break; - default: - panic("nipi unexpected number %d", nipi); - } + printf(" ipi %d", ipiirq); + + ampintc_intr_establish(ipiirq, IST_EDGE_RISING, + IPL_IPI|IPL_MPSAFE, NULL, ampintc_ipi_handler, sc, "ipi"); + sc->sc_ipi_num = ipiirq; intr_send_ipi_func = ampintc_send_ipi; #endif @@ -677,7 +640,7 @@ ampintc_cpuinit(void) * signal EOI here to make sure new interrupts will be * serviced. */ - ampintc_eoi(sc->sc_ipi_num[ARM_IPI_HALT]); + ampintc_eoi(sc->sc_ipi_num); } void @@ -1057,44 +1020,41 @@ ampintc_ipi_halt(void *v) } int -ampintc_ipi_nop(void *v) -{ - /* Nothing to do here, just enough to wake up from WFI */ - return 1; -} - -int -ampintc_ipi_combined(void *v) +ampintc_ipi_handler(void *v) { struct ampintc_softc *sc = (struct ampintc_softc *)v; + struct cpu_info *ci = curcpu(); + u_int reasons; - if (sc->sc_ipi_reason[cpu_number()] == ARM_IPI_DDB) { - sc->sc_ipi_reason[cpu_number()] = ARM_IPI_NOP; - return ampintc_ipi_ddb(v); - } else if (sc->sc_ipi_reason[cpu_number()] == ARM_IPI_HALT) { - sc->sc_ipi_reason[cpu_number()] = ARM_IPI_NOP; - return ampintc_ipi_halt(v); - } else { - return ampintc_ipi_nop(v); + reasons = sc->sc_ipi_reason[ci->ci_cpuid]; + if (reasons) { + reasons = atomic_swap_uint(&sc->sc_ipi_reason[ci->ci_cpuid], 0); + if (ISSET(reasons, 1 << ARM_IPI_DDB)) + ampintc_ipi_ddb(v); + if (ISSET(reasons, 1 << ARM_IPI_HALT)) + ampintc_ipi_halt(v); } + + return (1); } void -ampintc_send_ipi(struct cpu_info *ci, int id) +ampintc_send_ipi(struct cpu_info *ci, int reason) { struct ampintc_softc *sc = ampintc; int sendmask; - if (ci == curcpu() && id == ARM_IPI_NOP) - return; - - /* never overwrite IPI_DDB or IPI_HALT with IPI_NOP */ - if (id == ARM_IPI_DDB || id == ARM_IPI_HALT) - sc->sc_ipi_reason[ci->ci_cpuid] = id; + if (reason == ARM_IPI_NOP) { + if (ci == curcpu()) + return; + } else { + atomic_setbits_int(&sc->sc_ipi_reason[ci->ci_cpuid], + 1 << reason); + } /* currently will only send to one cpu */ sendmask = sc->sc_cpu_mask[ci->ci_cpuid] << 16; - sendmask |= sc->sc_ipi_num[id]; + sendmask |= sc->sc_ipi_num; bus_space_write_4(sc->sc_iot, sc->sc_d_ioh, ICD_SGIR, sendmask); } Index: aplintc.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/dev/aplintc.c,v diff -u -p -r1.18 aplintc.c --- aplintc.c 21 Dec 2022 22:30:42 -0000 1.18 +++ aplintc.c 4 Jul 2025 23:53:08 -0000 @@ -655,13 +655,13 @@ aplintc_send_ipi(struct cpu_info *ci, in struct aplintc_softc *sc = aplintc_sc; uint64_t sendmask; - if (ci == curcpu() && reason == ARM_IPI_NOP) - return; - - /* never overwrite IPI_DDB or IPI_HALT with IPI_NOP */ - if (reason == ARM_IPI_DDB || reason == ARM_IPI_HALT) - sc->sc_ipi_reason[ci->ci_cpuid] = reason; - membar_producer(); + if (reason == ARM_IPI_NOP) { + if (ci == curcpu()) + return; + } else { + atomic_setbits_int(&sc->sc_ipi_reason[ci->ci_cpuid], + 1 << reason); + } sendmask = (ci->ci_mpidr & MPIDR_AFF0); if ((curcpu()->ci_mpidr & MPIDR_AFF1) == (ci->ci_mpidr & MPIDR_AFF1)) { @@ -678,16 +678,17 @@ void aplintc_handle_ipi(struct aplintc_softc *sc) { struct cpu_info *ci = curcpu(); + u_int reasons; - membar_consumer(); - if (sc->sc_ipi_reason[ci->ci_cpuid] == ARM_IPI_DDB) { - sc->sc_ipi_reason[ci->ci_cpuid] = ARM_IPI_NOP; + reasons = sc->sc_ipi_reason[ci->ci_cpuid]; + if (reasons) { + reasons = atomic_swap_uint(&sc->sc_ipi_reason[ci->ci_cpuid], 0); #ifdef DDB - db_enter(); + if (ISSET(reasons, 1 << ARM_IPI_DDB)) + db_enter(); #endif - } else if (sc->sc_ipi_reason[ci->ci_cpuid] == ARM_IPI_HALT) { - sc->sc_ipi_reason[ci->ci_cpuid] = ARM_IPI_NOP; - cpu_halt(); + if (ISSET(reasons, 1 << ARM_IPI_HALT)) + cpu_halt(); } sc->sc_ipi_count.ec_count++; Index: bcm2836_intr.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/dev/bcm2836_intr.c,v diff -u -p -r1.15 bcm2836_intr.c --- bcm2836_intr.c 21 Dec 2022 22:30:42 -0000 1.15 +++ bcm2836_intr.c 4 Jul 2025 23:53:08 -0000 @@ -626,23 +626,18 @@ bcm_intc_handle_ipi(void) struct bcm_intc_softc *sc = bcm_intc; int cpuno = cpu_number(); uint32_t mbox_val; - int ipi; mbox_val = bus_space_read_4(sc->sc_iot, sc->sc_lioh, - ARM_LOCAL_INT_MAILBOX_CLR(cpuno)); - ipi = ffs(mbox_val) - 1; + ARM_LOCAL_INT_MAILBOX_CLR(cpuno)); bus_space_write_4(sc->sc_iot, sc->sc_lioh, - ARM_LOCAL_INT_MAILBOX_CLR(cpuno), 1 << ipi); - switch (ipi) { - case ARM_IPI_DDB: - /* XXX */ + ARM_LOCAL_INT_MAILBOX_CLR(cpuno), mbox_val); + #ifdef DDB + if (ISSET(mbox_val, 1 << ARM_IPI_DDB)) { + /* XXX */ db_enter(); -#endif - break; - case ARM_IPI_NOP: - break; } +#endif } void