Esempio n. 1
0
/*
 * Resume all paused cpus.
 */
void
cpu_resume_others(void)
{
	__cpuset_t cpuset;

	CPUSET_CLEAR(cpus_resumed);
	CPUSET_ASSIGN(cpuset, cpus_paused);
	CPUSET_CLEAR(cpus_paused);

	/* CPUs awake on cpus_paused clear */
	if (cpu_ipi_wait(&cpus_resumed, cpuset))
		cpu_ipi_error("resume", cpus_resumed, cpuset);
}
Esempio n. 2
0
/*
 * Resume a single cpu
 */
void
cpu_resume(int index)
{
	CPUSET_CLEAR(cpus_resumed);
	CPUSET_DEL(cpus_paused, index);

	if (cpu_ipi_wait(&cpus_resumed, CPUSET_SINGLE(index)))
		cpu_ipi_error("resume", cpus_resumed, CPUSET_SINGLE(index));
}
Esempio n. 3
0
/*
 * Resume all paused cpus.
 */
void
mp_resume_cpus(void)
{
	int i = 3;
	sparc64_cpuset_t cpuset;

	CPUSET_CLEAR(cpuset);	/* XXX: gcc -Wuninitialized */

	while (i-- > 0) {
		CPUSET_CLEAR(cpus_resumed);
		CPUSET_ASSIGN(cpuset, cpus_paused);
		membar_Sync();
		CPUSET_CLEAR(cpus_paused);

		/* CPUs awake on cpus_paused clear */
		if (!sparc64_ipi_wait(&cpus_resumed, cpuset))
			return;
	}
	sparc64_ipi_error("resume", cpus_resumed, cpuset);
}
Esempio n. 4
0
/*
 * Initialize IPI machinery.
 */
void
sparc64_ipi_init(void)
{

	/* Clear all cpu sets. */
	CPUSET_CLEAR(cpus_halted);
	CPUSET_CLEAR(cpus_spinning);
	CPUSET_CLEAR(cpus_paused);
	CPUSET_CLEAR(cpus_resumed);

	/*
	 * Prepare cpu type dependent function pointers
	 */

	if (CPU_ISSUN4V) {
		smp_tlb_flush_pte_func = sparc64_ipi_flush_pte_sun4v;
		sparc64_ipi_dcache_flush_page_func =
		    sparc64_ipi_dcache_flush_page_sun4v;
	}
	else if (CPU_IS_USIII_UP()) {
		smp_tlb_flush_pte_func = sparc64_ipi_flush_pte_usiii;
		sparc64_ipi_dcache_flush_page_func =
		    sparc64_ipi_dcache_flush_page_usiii;
	}
	else {
		smp_tlb_flush_pte_func = sparc64_ipi_flush_pte_us;
		sparc64_ipi_dcache_flush_page_func =
		    sparc64_ipi_dcache_flush_page_us;
	}

	if (CPU_ISSUN4V)
		sparc64_send_ipi = sparc64_send_ipi_sun4v;
	else
		sparc64_send_ipi = sparc64_send_ipi_sun4u;

}
Esempio n. 5
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);
		}
	}
}