aboutsummaryrefslogtreecommitdiff
path: root/shutdown/acpi_shutdown.c
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2019-03-02 15:31:04 -0800
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2019-03-02 15:32:08 -0800
commit99a69fd8b6034214c0729e9a3a684bbe9d541eb0 (patch)
tree5c6faf43f8e14bbfdb5647e396362a592ce08772 /shutdown/acpi_shutdown.c
parent33421955afb21c5e89a85f0b8f19c3644b18c8ae (diff)
downloadhurd-99a69fd8b6034214c0729e9a3a684bbe9d541eb0.tar.gz
hurd-99a69fd8b6034214c0729e9a3a684bbe9d541eb0.tar.bz2
hurd-99a69fd8b6034214c0729e9a3a684bbe9d541eb0.zip
Add shutdown RPC && ACPI specific disappear routine
* Makefile (prog-subdirs): Add shutdown. * hurd/hurd_types.defs (shutdown_t): New type. * hurd/hurd_types.h (shutdown_t): New type. * hurd/shutdown.defs: New file. * shutdown: New directory.
Diffstat (limited to 'shutdown/acpi_shutdown.c')
-rw-r--r--shutdown/acpi_shutdown.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/shutdown/acpi_shutdown.c b/shutdown/acpi_shutdown.c
new file mode 100644
index 00000000..af9b15d4
--- /dev/null
+++ b/shutdown/acpi_shutdown.c
@@ -0,0 +1,62 @@
+#include <stdio.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/io.h>
+#include <mach.h>
+#include "acpi_shutdown.h"
+
+void disappear_via_acpi(void)
+{
+ uint16_t i, pm1a_ctl, smi_cmd;
+ uint8_t regbuf[2], acpi_en;
+ FILE *facp;
+
+ /* Open the ACPI FADT table */
+ facp = fopen(SERVERS_ACPI_FADT, "r");
+ if (!facp)
+ exit(errno);
+
+ /* Grab value to write to SMI_CMD to enable ACPI */
+ fseek(facp, SMI_EN_OFFSET, SEEK_SET);
+ fread(&acpi_en, 1, 1, facp);
+
+ /* Grab SMI_CMD I/O port */
+ fseek(facp, SMI_CMD_OFFSET, SEEK_SET);
+ fread(regbuf, 2, 1, facp);
+ smi_cmd = (uint16_t)regbuf[0] |
+ ((uint16_t)regbuf[1] << 8);
+
+ /* Grab PM1a Control I/O port */
+ fseek(facp, PM1A_CTL_OFFSET, SEEK_SET);
+ fread(regbuf, 2, 1, facp);
+ pm1a_ctl = (uint16_t)regbuf[0] |
+ ((uint16_t)regbuf[1] << 8);
+
+ /* Close the ACPI FADT table */
+ fclose(facp);
+
+ /* Get I/O permissions */
+ if (ioperm(0, 0xffff, 1)) {
+ mach_print("EPERM on ioperm()\n");
+ return;
+ }
+
+ /* Enable ACPI */
+ outb(acpi_en, smi_cmd);
+ for (i = 0; i < 300; i++)
+ {
+ if ( (inw(pm1a_ctl) & SCI_EN) == SCI_EN)
+ break;
+ }
+
+ /* Kill machine */
+
+ /* try sleep state 5 first */
+ outw(SLP_TYP5 | SLP_EN, pm1a_ctl);
+
+ /* if we reach here then above did not work */
+ outw(SLP_TYP0 | SLP_EN, pm1a_ctl);
+
+ /* Never reached */
+}