aboutsummaryrefslogtreecommitdiffstats
path: root/com32
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-03-30 16:06:39 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2010-03-30 16:10:13 -0700
commitd6fb0861c55f062797c8706f484bd47ae0f94568 (patch)
tree058691551709427756f9d2469c1eaf47cd59917f /com32
parentb6e84b7f93c5b4a0cffd132f3c6dbf6bf58ba2b9 (diff)
downloadsyslinux-d6fb0861c55f062797c8706f484bd47ae0f94568.tar.gz
syslinux-d6fb0861c55f062797c8706f484bd47ae0f94568.tar.xz
syslinux-d6fb0861c55f062797c8706f484bd47ae0f94568.zip
core: move idle handling into protected mode
Do the actual idling in protected mode. This both allows PM code a more efficient interface, but also handles bugs in HVM implementations which don't handle HLT in real mode. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'com32')
-rw-r--r--com32/include/sys/cpu.h5
-rw-r--r--com32/include/syslinux/idle.h1
-rw-r--r--com32/include/syslinux/pmapi.h3
-rw-r--r--com32/lib/syslinux/idle.c24
4 files changed, 15 insertions, 18 deletions
diff --git a/com32/include/sys/cpu.h b/com32/include/sys/cpu.h
index d96ec665..a798a840 100644
--- a/com32/include/sys/cpu.h
+++ b/com32/include/sys/cpu.h
@@ -105,7 +105,10 @@ static inline void cpu_relax(void)
asm volatile ("rep ; nop");
}
-/* These are local cli/sti; not SMP-safe!!! */
+static inline void hlt(void)
+{
+ asm volatile ("hlt");
+}
static inline void cli(void)
{
diff --git a/com32/include/syslinux/idle.h b/com32/include/syslinux/idle.h
index 4c5947b7..6a45236e 100644
--- a/com32/include/syslinux/idle.h
+++ b/com32/include/syslinux/idle.h
@@ -33,5 +33,6 @@
#define _SYSLINUX_IDLE_H
void syslinux_idle(void);
+void syslinux_reset_idle(void);
#endif
diff --git a/com32/include/syslinux/pmapi.h b/com32/include/syslinux/pmapi.h
index 5631dcba..f583deae 100644
--- a/com32/include/syslinux/pmapi.h
+++ b/com32/include/syslinux/pmapi.h
@@ -62,6 +62,9 @@ struct com32_pmapi {
struct _DIR_ *(*opendir)(const char *);
struct dirent *(*readdir)(struct _DIR_ *);
int (*closedir)(struct _DIR_ *);
+
+ void (*idle)(void);
+ void (*reset_idle)(void);
};
#endif /* _SYSLINUX_PMAPI_H */
diff --git a/com32/lib/syslinux/idle.c b/com32/lib/syslinux/idle.c
index 8a0d206c..ddaa7fcd 100644
--- a/com32/lib/syslinux/idle.c
+++ b/com32/lib/syslinux/idle.c
@@ -33,25 +33,15 @@
#include <stddef.h>
#include <com32.h>
-#include <sys/cpu.h>
+#include <syslinux/pmapi.h>
#include <syslinux/idle.h>
-void syslinux_idle(void)
+void syslinux_reset_idle(void)
{
- static int do_idle = 1;
- static const com32sys_t sys_idle = {
- .eax.l = 0x0013,
- };
- com32sys_t idle_result;
-
- /* This call isn't supported on SYSLINUX < 3.08, but all it does
- is return an error, so we don't care. */
-
- if (do_idle) {
- __intcall(0x22, &sys_idle, &idle_result);
-
- do_idle = ~idle_result.eflags.l & EFLAGS_CF;
- }
+ __com32.cs_pm->reset_idle();
+}
- cpu_relax();
+void syslinux_idle(void)
+{
+ __com32.cs_pm->idle();
}