summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
authorMike Larkin <mlarkin@cvs.openbsd.org>2013-06-01 22:22:14 +0000
committerMike Larkin <mlarkin@cvs.openbsd.org>2013-06-01 22:22:14 +0000
commit9c1253759d48324639d599b362997fcfc87324b2 (patch)
tree4d09f3dadf25d4d82ab4f8c954ec7d0ad48907aa /sys/arch/amd64
parenta638f352652004c9408641d59ffbcaa72ab89a67 (diff)
Introduce a new amd64 IPI, x86_ipi_halt_realmode to park CPUS into real
mode and halt them. Needed for hibernate. ok deraadt@ kettenis@ "there's no risk there"
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/amd64/ipifuncs.c29
-rw-r--r--sys/arch/amd64/include/intrdefs.h8
2 files changed, 33 insertions, 4 deletions
diff --git a/sys/arch/amd64/amd64/ipifuncs.c b/sys/arch/amd64/amd64/ipifuncs.c
index ad60e6944de..c7729469464 100644
--- a/sys/arch/amd64/amd64/ipifuncs.c
+++ b/sys/arch/amd64/amd64/ipifuncs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipifuncs.c,v 1.18 2013/03/20 21:23:05 kettenis Exp $ */
+/* $OpenBSD: ipifuncs.c,v 1.19 2013/06/01 22:22:13 mlarkin Exp $ */
/* $NetBSD: ipifuncs.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */
/*-
@@ -62,6 +62,11 @@ void x86_64_ipi_halt(struct cpu_info *);
void x86_64_ipi_synch_fpu(struct cpu_info *);
void x86_64_ipi_flush_fpu(struct cpu_info *);
+#ifdef HIBERNATE
+void x86_64_ipi_halt_realmode(struct cpu_info *);
+extern void hibernate_drop_to_real_mode(void);
+#endif /* HIBERNATE */
+
#if NMTRR > 0
void x86_64_ipi_reload_mtrr(struct cpu_info *);
#else
@@ -82,6 +87,11 @@ void (*ipifunc[X86_NIPI])(struct cpu_info *) =
#else
NULL,
#endif
+#ifdef HIBERNATE
+ x86_64_ipi_halt_realmode,
+#else
+ NULL,
+#endif /* HIBERNATE */
};
void
@@ -126,3 +136,20 @@ x86_64_ipi_reload_mtrr(struct cpu_info *ci)
mem_range_softc.mr_op->reload(&mem_range_softc);
}
#endif
+
+#ifdef HIBERNATE
+void
+x86_64_ipi_halt_realmode(struct cpu_info *ci)
+{
+ /* Halt CPUs and park in real mode */
+
+ SCHED_ASSERT_UNLOCKED();
+ fpusave_cpu(ci, 1);
+ disable_intr();
+ wbinvd();
+ ci->ci_flags &= ~CPUF_RUNNING;
+ wbinvd();
+
+ hibernate_drop_to_real_mode();
+}
+#endif /* HIBERNATE */
diff --git a/sys/arch/amd64/include/intrdefs.h b/sys/arch/amd64/include/intrdefs.h
index 0d76886cc95..b08eda38d1b 100644
--- a/sys/arch/amd64/include/intrdefs.h
+++ b/sys/arch/amd64/include/intrdefs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intrdefs.h,v 1.10 2013/05/16 16:20:00 kettenis Exp $ */
+/* $OpenBSD: intrdefs.h,v 1.11 2013/06/01 22:22:13 mlarkin Exp $ */
/* $NetBSD: intrdefs.h,v 1.2 2003/05/04 22:01:56 fvdl Exp $ */
#ifndef _AMD64_INTRDEFS_H
@@ -79,12 +79,14 @@
#define X86_IPI_MTRR 0x00000020
#define X86_IPI_SETPERF 0x00000040
#define X86_IPI_DDB 0x00000080
+#define X86_IPI_HALT_REALMODE 0x00000100
-#define X86_NIPI 8
+#define X86_NIPI 9
#define X86_IPI_NAMES { "halt IPI", "nop IPI", "FPU flush IPI", \
"FPU synch IPI", "TLB shootdown IPI", \
- "MTRR update IPI", "setperf IPI", "ddb IPI" }
+ "MTRR update IPI", "setperf IPI", "ddb IPI", \
+ "realmode halt IPI" }
#define IREENT_MAGIC 0x18041969