diff options
author | Damien Zammit <damien@zamaudio.com> | 2022-09-12 10:39:45 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2022-09-12 20:32:59 +0200 |
commit | 4830c981325d53f8a4372288dbf0ef77a22059da (patch) | |
tree | 892cd79901ed178e964cbfc25da90ec2bbb99fa9 /shutdown | |
parent | 160fb63ee0c72f165ab131c4d725d9badaa646ab (diff) | |
download | hurd-4830c981325d53f8a4372288dbf0ef77a22059da.tar.gz hurd-4830c981325d53f8a4372288dbf0ef77a22059da.tar.bz2 hurd-4830c981325d53f8a4372288dbf0ef77a22059da.zip |
shutdown: Use new acpi RPC to halt machine, clean up
This allows clean shutdown of all modern x86 machines
(not just qemu) by using the acpi translator to call
into libacpica code.
Message-Id: <20220912103837.556815-3-damien@zamaudio.com>
Diffstat (limited to 'shutdown')
-rw-r--r-- | shutdown/Makefile | 2 | ||||
-rw-r--r-- | shutdown/acpi_shutdown.c | 66 | ||||
-rw-r--r-- | shutdown/acpi_shutdown.h | 18 | ||||
-rw-r--r-- | shutdown/shutdown.c | 16 |
4 files changed, 14 insertions, 88 deletions
diff --git a/shutdown/Makefile b/shutdown/Makefile index 73813dab..fc5e697d 100644 --- a/shutdown/Makefile +++ b/shutdown/Makefile @@ -18,7 +18,7 @@ dir := shutdown makemode := server -SRCS = shutdown.c acpi_shutdown.c +SRCS = shutdown.c acpiUser.c HURDLIBS = ports shouldbeinlibc trivfs iohelp ihash fshelp LDLIBS = -lpthread target = shutdown diff --git a/shutdown/acpi_shutdown.c b/shutdown/acpi_shutdown.c deleted file mode 100644 index fde70111..00000000 --- a/shutdown/acpi_shutdown.c +++ /dev/null @@ -1,66 +0,0 @@ -#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(smi_cmd, 2, 1)) { - fprintf(stderr, "EPERM on ioperm(smi_cmd)\n"); - return; - } - if (ioperm(pm1a_ctl, 2, 1)) { - fprintf(stderr, "EPERM on ioperm(pm1a_ctl)\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 */ -} diff --git a/shutdown/acpi_shutdown.h b/shutdown/acpi_shutdown.h deleted file mode 100644 index 50b7f1f6..00000000 --- a/shutdown/acpi_shutdown.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _ACPI_SHUTDOWN_H_ -#define _ACPI_SHUTDOWN_H_ - -#include <hurd/paths.h> - -#define _SERVERS_ACPI _SERVERS "/acpi/tables" -#define SERVERS_ACPI_FADT _SERVERS_ACPI "/FACP" -#define SLP_TYP0 (0x0 << 10) -#define SLP_TYP5 (0x5 << 10) -#define SLP_EN (0x1 << 13) -#define SCI_EN 1 -#define SMI_CMD_OFFSET 12 -#define SMI_EN_OFFSET 16 -#define PM1A_CTL_OFFSET 28 - -void disappear_via_acpi(void); - -#endif diff --git a/shutdown/shutdown.c b/shutdown/shutdown.c index f821b1f2..e4247397 100644 --- a/shutdown/shutdown.c +++ b/shutdown/shutdown.c @@ -35,8 +35,10 @@ #include <sys/file.h> #include <version.h> -#include "acpi_shutdown.h" #include "shutdown_S.h" +#include "acpi_U.h" + +#define SLEEP_STATE_S5 5 /* Port bucket we service requests on. */ struct port_bucket *port_bucket; @@ -56,8 +58,16 @@ struct port_class *trivfs_control_class; kern_return_t S_shutdown_shutdown(trivfs_protid_t server) { - disappear_via_acpi(); - return 0; + kern_return_t err; + mach_port_t acpi; + + acpi = file_name_lookup (_SERVERS_ACPI, O_RDWR, 0); + if (acpi == MACH_PORT_NULL) + return EIO; + + err = acpi_sleep(acpi, SLEEP_STATE_S5); + + return err; } static int |