summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2009-03-17 00:48:11 +0000
committerjkim <jkim@FreeBSD.org>2009-03-17 00:48:11 +0000
commit3eda4741daa9db3ec9fa89000bfbf69dd182e01e (patch)
treec75b77d8208c29993db8a02658e1f33e9e5339b8 /sys/kern
parent4e75ea04f545069138b54e1fee5b5c1236ba5b68 (diff)
downloadFreeBSD-src-3eda4741daa9db3ec9fa89000bfbf69dd182e01e.zip
FreeBSD-src-3eda4741daa9db3ec9fa89000bfbf69dd182e01e.tar.gz
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.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/subr_smp.c48
1 files changed, 48 insertions, 0 deletions
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.
*
OpenPOWER on IntegriCloud