static void
cpu_ipi_error(const char *s, __cpuset_t succeeded, __cpuset_t expected)
{
	CPUSET_SUB(expected, succeeded);
	if (!CPUSET_EMPTY_P(expected)) {
		printf("Failed to %s:", s);
		do {
			int index = CPUSET_NEXT(expected);
			CPUSET_DEL(expected, index);
			printf(" cpu%d", index);
		} while (!CPUSET_EMPTY_P(expected));
		printf("\n");
	}
}
Beispiel #2
0
/*
 * Pause all cpus but ourselves.
 */
void
mp_pause_cpus(void)
{
	int i = 3;
	sparc64_cpuset_t cpuset;

	CPUSET_ASSIGN(cpuset, cpus_active);
	CPUSET_DEL(cpuset, cpu_number());
	while (i-- > 0) {
		if (CPUSET_EMPTY(cpuset))
			return;

		sparc64_multicast_ipi(cpuset, sparc64_ipi_pause, 0, 0);
		if (!sparc64_ipi_wait(&cpus_paused, cpuset))
			return;
		CPUSET_SUB(cpuset, cpus_paused);
	}
	sparc64_ipi_error("pause", cpus_paused, cpuset);
}
Beispiel #3
0
/*
 * Halt all cpus but ourselves.
 */
void
mp_halt_cpus(void)
{
	sparc64_cpuset_t cpumask, cpuset;
	struct cpu_info *ci;

	CPUSET_ASSIGN(cpuset, cpus_active);
	CPUSET_DEL(cpuset, cpu_number());
	CPUSET_ASSIGN(cpumask, cpuset);
	CPUSET_SUB(cpuset, cpus_halted);

	if (CPUSET_EMPTY(cpuset))
		return;

	CPUSET_CLEAR(cpus_spinning);
	sparc64_multicast_ipi(cpuset, sparc64_ipi_halt, 0, 0);
	if (sparc64_ipi_wait(&cpus_halted, cpumask))
		sparc64_ipi_error("halt", cpumask, cpus_halted);

	/*
	 * Depending on available firmware methods, other cpus will
	 * either shut down themselfs, or spin and wait for us to
	 * stop them.
	 */
	if (CPUSET_EMPTY(cpus_spinning)) {
		/* give other cpus a few cycles to actually power down */
		delay(10000);
		return;
	}
	/* there are cpus spinning - shut them down if we can */
	if (prom_has_stop_other()) {
		for (ci = cpus; ci != NULL; ci = ci->ci_next) {
			if (!CPUSET_HAS(cpus_spinning, ci->ci_index)) continue;
			prom_stop_other(ci->ci_cpuid);
		}
	}
}
/*
 * Halt all running cpus, excluding current cpu.
 */
void
cpu_halt_others(void)
{
	__cpuset_t cpumask, cpuset;

	CPUSET_ASSIGN(cpuset, cpus_running);
	CPUSET_DEL(cpuset, cpu_index(curcpu()));
	CPUSET_ASSIGN(cpumask, cpuset);
	CPUSET_SUB(cpuset, cpus_halted);

	if (CPUSET_EMPTY_P(cpuset))
		return;

	cpu_multicast_ipi(cpuset, IPI_HALT);
	if (cpu_ipi_wait(&cpus_halted, cpumask))
		cpu_ipi_error("halt", cpumask, cpus_halted);

	/*
	 * TBD
	 * Depending on available firmware methods, other cpus will
	 * either shut down themselfs, or spin and wait for us to
	 * stop them.
	 */
}