diff options
author | Sebastian Herbszt <herbszt@gmx.de> | 2013-02-10 19:30:51 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-02-11 13:13:24 +0000 |
commit | 88f8ad6a7721a7c1dcb5fc756906f8ccd90f6cfe (patch) | |
tree | 8d00e92252aa03fc1c7cd41a06a22c97867a3c00 | |
parent | 6f7b0e4a33e4064c8e814cbebeacf7206c9fb850 (diff) | |
download | syslinux-88f8ad6a7721a7c1dcb5fc756906f8ccd90f6cfe.tar.gz syslinux-88f8ad6a7721a7c1dcb5fc756906f8ccd90f6cfe.tar.xz syslinux-88f8ad6a7721a7c1dcb5fc756906f8ccd90f6cfe.zip |
poweroff COM32 module
This module is able to power off a system via APM.
It replaces the poweroff COMBOOT module.
Signed-off-by: Sebastian Herbszt <herbszt@gmx.de>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r-- | com32/modules/Makefile | 2 | ||||
-rw-r--r-- | com32/modules/poweroff.c | 88 |
2 files changed, 89 insertions, 1 deletions
diff --git a/com32/modules/Makefile b/com32/modules/Makefile index 628fa5d6..1998a0ef 100644 --- a/com32/modules/Makefile +++ b/com32/modules/Makefile @@ -25,7 +25,7 @@ MODULES = config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \ kbdmap.c32 cmd.c32 vpdtest.c32 host.c32 ls.c32 gpxecmd.c32 \ ifcpu.c32 cpuid.c32 cat.c32 pwd.c32 ifplop.c32 zzjson.c32 \ whichsys.c32 prdhcp.c32 pxechn.c32 kontron_wdt.c32 ifmemdsk.c32 \ - hexdump.c32 + hexdump.c32 poweroff.c32 TESTFILES = diff --git a/com32/modules/poweroff.c b/com32/modules/poweroff.c new file mode 100644 index 00000000..8b656ad4 --- /dev/null +++ b/com32/modules/poweroff.c @@ -0,0 +1,88 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2013 Sebastian Herbszt - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston MA 02110-1301, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * poweroff.c + * + * APM poweroff module + */ + +#include <stdio.h> +#include <string.h> +#include <com32.h> + +int main() +{ + com32sys_t inregs, outregs; + + memset(&inregs, 0, sizeof inregs); + + inregs.eax.l = 0x5300; /* APM Installation Check (00h) */ + inregs.ebx.l = 0; /* APM BIOS (0000h) */ + __intcall(0x15, &inregs, &outregs); + + if (outregs.eflags.l & EFLAGS_CF) { + printf("APM not present.\n"); + return 1; + } + + if ((outregs.ebx.l & 0xffff) != 0x504d) { /* signature 'PM' */ + printf("APM not present.\n"); + return 1; + } + + if ((outregs.eax.l & 0xffff) < 0x101) { /* Need version 1.1+ */ + printf("APM 1.1+ not supported.\n"); + return 1; + } + + if ((outregs.ecx.l & 0x8) == 0x8) { /* bit 3 APM BIOS Power Management disabled */ + printf("Power management disabled.\n"); + return 1; + } + + inregs.eax.l = 0x5301; /* APM Real Mode Interface Connect (01h) */ + inregs.ebx.l = 0; /* APM BIOS (0000h) */ + __intcall(0x15, &inregs, &outregs); + + if (outregs.eflags.l & EFLAGS_CF) { + printf("APM RM interface connect failed.\n"); + return 1; + } + + inregs.eax.l = 0x530e; /* APM Driver Version (0Eh) */ + inregs.ebx.l = 0; /* APM BIOS (0000h) */ + inregs.ecx.l = 0x101; /* APM Driver version 1.1 */ + __intcall(0x15, &inregs, &outregs); + + if (outregs.eflags.l & EFLAGS_CF) { + printf("APM 1.1+ not supported.\n"); + return 1; + } + + if ((outregs.ecx.l & 0xffff) < 0x101) { /* APM Connection version */ + printf("APM 1.1+ not supported.\n"); + return 1; + } + + inregs.eax.l = 0x5307; /* Set Power State (07h) */ + inregs.ebx.l = 1; /* All devices power managed by the APM BIOS */ + inregs.ecx.l = 3; /* Power state off */ + __intcall(0x15, &inregs, &outregs); + + if (outregs.eflags.l & EFLAGS_CF) { + printf("Power off failed.\n"); + return 1; + } + + return 0; +} |