From 3eda4741daa9db3ec9fa89000bfbf69dd182e01e Mon Sep 17 00:00:00 2001 From: jkim Date: Tue, 17 Mar 2009 00:48:11 +0000 Subject: Initial suspend/resume support for amd64. This code is heavily inspired by Takanori Watanabe's experimental SMP patch for i386 and large portion was shamelessly cut and pasted from Peter Wemm's AP boot code. --- sys/kern/subr_smp.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'sys/kern') diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index e807e48..1a3a6fa 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -262,6 +262,54 @@ stop_cpus(cpumask_t map) return 1; } +#if defined(__amd64__) +/* + * When called the executing CPU will send an IPI to all other CPUs + * requesting that they halt execution. + * + * Usually (but not necessarily) called with 'other_cpus' as its arg. + * + * - Signals all CPUs in map to suspend. + * - Waits for each to suspend. + * + * Returns: + * -1: error + * 0: NA + * 1: ok + * + * XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs + * from executing at same time. + */ +int +suspend_cpus(cpumask_t map) +{ + int i; + + if (!smp_started) + return (0); + + CTR1(KTR_SMP, "suspend_cpus(%x)", map); + + /* send the suspend IPI to all CPUs in map */ + ipi_selected(map, IPI_SUSPEND); + + i = 0; + while ((stopped_cpus & map) != map) { + /* spin */ + cpu_spinwait(); + i++; +#ifdef DIAGNOSTIC + if (i == 100000) { + printf("timeout suspending cpus\n"); + break; + } +#endif + } + + return (1); +} +#endif + /* * Called by a CPU to restart stopped CPUs. * -- cgit v1.1