diff options
author | Mike Larkin <mlarkin@cvs.openbsd.org> | 2013-06-01 22:22:14 +0000 |
---|---|---|
committer | Mike Larkin <mlarkin@cvs.openbsd.org> | 2013-06-01 22:22:14 +0000 |
commit | 9c1253759d48324639d599b362997fcfc87324b2 (patch) | |
tree | 4d09f3dadf25d4d82ab4f8c954ec7d0ad48907aa /sys/arch/amd64 | |
parent | a638f352652004c9408641d59ffbcaa72ab89a67 (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.c | 29 | ||||
-rw-r--r-- | sys/arch/amd64/include/intrdefs.h | 8 |
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 |