diff options
author | Damien Zammit <damien@zamaudio.com> | 2019-03-02 15:31:04 -0800 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2019-03-02 15:32:08 -0800 |
commit | 99a69fd8b6034214c0729e9a3a684bbe9d541eb0 (patch) | |
tree | 5c6faf43f8e14bbfdb5647e396362a592ce08772 /shutdown/acpi_shutdown.c | |
parent | 33421955afb21c5e89a85f0b8f19c3644b18c8ae (diff) | |
download | hurd-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.c | 62 |
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 */ +} |