Beispiel #1
0
/*
 * 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);
		}
	}
}
Beispiel #2
0
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);
	}
}
Beispiel #3
0
/*
 * 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);
		}
	}
}
Beispiel #4
0
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
}