RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
{
#if __FreeBSD_version >= 900000
    cpuset_t    Mask;
#elif  __FreeBSD_version >= 700000
    cpumask_t   Mask;
#endif
    RTMPARGS    Args;

    /* Will panic if no rendezvousing cpus, so make sure the cpu is online. */
    if (!RTMpIsCpuOnline(idCpu))
        return VERR_CPU_NOT_FOUND;

    Args.pfnWorker = pfnWorker;
    Args.pvUser1 = pvUser1;
    Args.pvUser2 = pvUser2;
    Args.idCpu = idCpu;
    Args.cHits = 0;
#if __FreeBSD_version >= 700000
# if __FreeBSD_version >= 900000
    CPU_SETOF(idCpu, &Mask);
# else
    Mask = (cpumask_t)1 << idCpu;
# endif
    smp_rendezvous_cpus(Mask, NULL, rtmpOnSpecificFreeBSDWrapper, smp_no_rendezvous_barrier, &Args);
#else
    smp_rendezvous(NULL, rtmpOnSpecificFreeBSDWrapper, NULL, &Args);
#endif
    return Args.cHits == 1
         ? VINF_SUCCESS
         : VERR_CPU_NOT_FOUND;
}
Example #2
0
int
cpu_mp_probe(void)
{

	/*
	 * Always record BSP in CPU map so that the mbuf init code works
	 * correctly.
	 */
	CPU_SETOF(0, &all_cpus);
	if (mp_ncpus == 0) {
		/*
		 * No CPUs were found, so this must be a UP system.  Setup
		 * the variables to represent a system with a single CPU
		 * with an id of 0.
		 */
		mp_ncpus = 1;
		return (0);
	}

	/* At least one CPU was found. */
	if (mp_ncpus == 1) {
		/*
		 * One CPU was found, so this must be a UP system with
		 * an I/O APIC.
		 */
		return (0);
	}

	/* At least two CPUs were found. */
	return (1);
}
Example #3
0
/* Determine if we running MP machine */
int
cpu_mp_probe(void)
{
	CPU_SETOF(0, &all_cpus);

	return (platform_mp_probe());
}
Example #4
0
/*
 * Provide dummy SMP support for UP kernels.  Modules that need to use SMP
 * APIs will still work using this dummy support.
 */
static void
mp_setvariables_for_up(void *dummy)
{
	mp_ncpus = 1;
	mp_maxid = PCPU_GET(cpuid);
	CPU_SETOF(mp_maxid, &all_cpus);
	KASSERT(PCPU_GET(cpuid) == 0, ("UP must have a CPU ID of zero"));
}
Example #5
0
static void xcall(cyb_arg_t arg __unused, cpu_t *c, cyc_func_t func,
    void *param)
{
	cpuset_t cpus;

	CPU_SETOF(c->cpuid, &cpus);
	smp_rendezvous_cpus(cpus,
	    smp_no_rendevous_barrier, func, smp_no_rendevous_barrier, param);
}
Example #6
0
/* Determine if we running MP machine */
int
cpu_mp_probe(void)
{

	KASSERT(mp_ncpus != 0, ("cpu_mp_probe: mp_ncpus is unset"));

	CPU_SETOF(0, &all_cpus);

	return (mp_ncpus > 1);
}
Example #7
0
/*
 * Probe for other CPUs.
 */
void
cpu_mp_setmaxid(void)
{

	CPU_SETOF(curcpu, &all_cpus);
	mp_ncpus = 1;

	foreach_ap(OF_child(OF_peer(0)), ap_count);
	mp_ncpus = MIN(mp_ncpus, MAXCPU);
	mp_maxid = mp_ncpus - 1;
}
Example #8
0
void
dtrace_xcall(processorid_t cpu, dtrace_xcall_t func, void *arg)
{
	cpuset_t cpus;

	if (cpu == DTRACE_CPUALL)
		cpus = all_cpus;
	else
		CPU_SETOF(cpu, &cpus);

	smp_rendezvous_cpus(cpus, smp_no_rendevous_barrier, func,
	    smp_no_rendevous_barrier, arg);
}
Example #9
0
static void
cpu_reset_proxy()
{
	cpuset_t tcrp;

	cpu_reset_proxy_active = 1;
	while (cpu_reset_proxy_active == 1)
		ia32_pause(); /* Wait for other cpu to see that we've started */

	CPU_SETOF(cpu_reset_proxyid, &tcrp);
	stop_cpus(tcrp);
	printf("cpu_reset_proxy: Stopped CPU %d\n", cpu_reset_proxyid);
	DELAY(1000000);
	cpu_reset_real();
}
Example #10
0
void
cpu_reset()
{
#ifdef SMP
	cpuset_t map;
	u_int cnt;

	if (smp_started) {
		map = all_cpus;
		CPU_CLR(PCPU_GET(cpuid), &map);
		CPU_NAND(&map, &stopped_cpus);
		if (!CPU_EMPTY(&map)) {
			printf("cpu_reset: Stopping other CPUs\n");
			stop_cpus(map);
		}

		if (PCPU_GET(cpuid) != 0) {
			cpu_reset_proxyid = PCPU_GET(cpuid);
			cpustop_restartfunc = cpu_reset_proxy;
			cpu_reset_proxy_active = 0;
			printf("cpu_reset: Restarting BSP\n");

			/* Restart CPU #0. */
			CPU_SETOF(0, &started_cpus);
			wmb();

			cnt = 0;
			while (cpu_reset_proxy_active == 0 && cnt < 10000000) {
				ia32_pause();
				cnt++;	/* Wait for BSP to announce restart */
			}
			if (cpu_reset_proxy_active == 0)
				printf("cpu_reset: Failed to restart BSP\n");
			enable_intr();
			cpu_reset_proxy_active = 2;

			while (1)
				ia32_pause();
			/* NOTREACHED */
		}

		DELAY(1000000);
	}
#endif
	cpu_reset_real();
	/* NOTREACHED */
}
Example #11
0
/*
 * Call the MD SMP initialization code.
 */
static void
mp_start(void *dummy)
{

	mtx_init(&smp_ipi_mtx, "smp rendezvous", NULL, MTX_SPIN);

	/* Probe for MP hardware. */
	if (smp_disabled != 0 || cpu_mp_probe() == 0) {
		mp_ncpus = 1;
		CPU_SETOF(PCPU_GET(cpuid), &all_cpus);
		return;
	}

	cpu_mp_start();
	printf("FreeBSD/SMP: Multiprocessor System Detected: %d CPUs\n",
	    mp_ncpus);
	cpu_mp_announce();
}
RTDECL(int) RTMpPokeCpu(RTCPUID idCpu)
{
#if __FreeBSD_version >= 900000
    cpuset_t    Mask;
#elif  __FreeBSD_version >= 700000
    cpumask_t   Mask;
#endif

    /* Will panic if no rendezvousing cpus, so make sure the cpu is online. */
    if (!RTMpIsCpuOnline(idCpu))
        return VERR_CPU_NOT_FOUND;

# if __FreeBSD_version >= 900000
    CPU_SETOF(idCpu, &Mask);
# else
    Mask = (cpumask_t)1 << idCpu;
# endif
    smp_rendezvous_cpus(Mask, NULL, rtmpFreeBSDPokeCallback, smp_no_rendezvous_barrier, NULL);

    return VINF_SUCCESS;
}
Example #13
0
struct cpu_group *
smp_topo_find(struct cpu_group *top, int cpu)
{
	struct cpu_group *cg;
	cpuset_t mask;
	int children;
	int i;

	CPU_SETOF(cpu, &mask);
	cg = top;
	for (;;) {
		if (!CPU_OVERLAP(&cg->cg_mask, &mask))
			return (NULL);
		if (cg->cg_children == 0)
			return (cg);
		children = cg->cg_children;
		for (i = 0, cg = cg->cg_child; i < children; cg++, i++)
			if (CPU_OVERLAP(&cg->cg_mask, &mask))
				break;
	}
	return (NULL);
}