/* * Flush pte on all active processors. */ void smp_tlb_flush_pte(vaddr_t va, struct pmap * pm) { sparc64_cpuset_t cpuset; struct cpu_info *ci; int ctx; bool kpm = (pm == pmap_kernel()); /* Flush our own TLB */ ctx = pm->pm_ctx[cpu_number()]; KASSERT(ctx >= 0); if (kpm || ctx > 0) sp_tlb_flush_pte(va, ctx); CPUSET_ASSIGN(cpuset, cpus_active); CPUSET_DEL(cpuset, cpu_number()); if (CPUSET_EMPTY(cpuset)) return; /* Flush others */ for (ci = cpus; ci != NULL; ci = ci->ci_next) { if (CPUSET_HAS(cpuset, ci->ci_index)) { CPUSET_DEL(cpuset, ci->ci_index); ctx = pm->pm_ctx[ci->ci_index]; KASSERT(ctx >= 0); if (!kpm && ctx == 0) continue; sparc64_send_ipi(ci->ci_cpuid, smp_tlb_flush_pte_func, va, ctx); } } }
void sparc64_generic_xcall(struct cpu_info *target, ipi_c_call_func_t func, void *arg) { /* if target == NULL broadcast to everything but curcpu */ if (target) sparc64_send_ipi(target->ci_cpuid, sparc64_ipi_ccall, (uint64_t)(uintptr_t)func, (uint64_t)(uintptr_t)arg); else { sparc64_multicast_ipi(cpus_active, sparc64_ipi_ccall, (uint64_t)(uintptr_t)func, (uint64_t)(uintptr_t)arg); } }
/* * Send an IPI to all in the list but ourselves. */ void sparc64_multicast_ipi(sparc64_cpuset_t cpuset, ipifunc_t func, uint64_t arg1, uint64_t arg2) { struct cpu_info *ci; CPUSET_DEL(cpuset, cpu_number()); if (CPUSET_EMPTY(cpuset)) return; for (ci = cpus; ci != NULL; ci = ci->ci_next) { if (CPUSET_HAS(cpuset, ci->ci_index)) { CPUSET_DEL(cpuset, ci->ci_index); sparc64_send_ipi(ci->ci_cpuid, func, arg1, arg2); } } }
void fpusave_lwp(struct lwp *l, bool save) { #ifdef MULTIPROCESSOR volatile struct cpu_info *ci; if (l == fplwp) { int s = intr_disable(); fpusave_cpu(save); intr_restore(s); return; } for (ci = cpus; ci != NULL; ci = ci->ci_next) { int spincount; if (ci == curcpu() || !CPUSET_HAS(cpus_active, ci->ci_index)) continue; if (ci->ci_fplwp != l) continue; sparc64_send_ipi(ci->ci_cpuid, save ? sparc64_ipi_save_fpstate : sparc64_ipi_drop_fpstate, (uintptr_t)l, 0); spincount = 0; while (ci->ci_fplwp == l) { membar_Sync(); spincount++; if (spincount > 10000000) panic("fpusave_lwp ipi didn't"); } break; } #else if (l == fplwp) fpusave_cpu(save); #endif }