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"); } }
/* * 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); }
/* * 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. */ }