/* * Initialize IPI state for a CPU. */ void mips64_ipi_init(void) { cpuid_t cpuid = cpu_number(); int error; if (!cpuid) mtx_init(&smp_ipi_mtx, IPL_IPI); hw_ipi_intr_clear(cpuid); error = hw_ipi_intr_establish(mips64_ipi_intr, cpuid); if (error) panic("hw_ipi_intr_establish failed:%d", error); }
/* * Process IPIs for a CPU. */ int mips64_ipi_intr(void *arg) { unsigned int pending_ipis, bit; unsigned int cpuid = (unsigned int)(unsigned long)arg; KASSERT (cpuid == cpu_number()); /* clear ipi interrupt */ hw_ipi_intr_clear(cpuid); /* get and clear pending ipis */ pending_ipis = atomic_swap_uint(&ipi_mailbox[cpuid], 0); if (pending_ipis > 0) { for (bit = 0; bit < MIPS64_NIPIS; bit++) if (pending_ipis & (1UL << bit)) (*ipifuncs[bit])(); } return 1; }
/* * Process IPIs for a CPU. */ static int mips64_ipi_intr(void *arg) { unsigned int pending_ipis, bit; unsigned int cpuid = (unsigned int)(unsigned long)arg; KASSERT (cpuid == cpu_number()); /* figure out which ipi are pending */ pending_ipis = ipi_mailbox[cpuid]; /* clear ipi interrupt */ hw_ipi_intr_clear(cpuid); if (pending_ipis > 0) { /* clear pending ipi, since we're about to handle them */ atomic_clearbits_int(&ipi_mailbox[cpuid], pending_ipis); for (bit = 0; bit < MIPS64_NIPIS; bit++) if (pending_ipis & (1UL << bit)) (*ipifuncs[bit])(); } return 1; }