From d28d3fb35285d6a8b4a23cfbc713fd15465952c4 Mon Sep 17 00:00:00 2001 From: kettenis Date: Sun, 9 May 2021 15:51:35 +0000 Subject: [PATCH] Some x86 machines advertise the "hardware reduced" ACPI feature, advertise S4 and S5 support, but fail to populate the SLEEP_CONTROL_REG and SLEEP_STATUS_REG descriptions in the FADT. An example of such a machine is the ASUS Zenbook 14 UM433DA. Any attempt to powerdown the machine will result in a kernel crash. It turns out that using the legacy ACPI PM registers works fine on this machien. So fall back on those registers if SLEEP_CONTROL_REG and/or SLEEP_STATUS_REG aren't provided. ok deraadt@, mpi@ --- sys/dev/acpi/acpi.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index f39e9231599..51753fcedf1 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.397 2021/03/15 22:44:57 patrick Exp $ */ +/* $OpenBSD: acpi.c,v 1.398 2021/05/09 15:51:35 kettenis Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert * Copyright (c) 2005 Jordan Hargrave @@ -1436,7 +1436,8 @@ acpi_read_pmreg(struct acpi_softc *sc, int reg, int offset) * For Hardware-reduced ACPI we also emulate PM1A_STS using * SLEEP_STATUS_REG. */ - if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_STS) { + if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_STS && + sc->sc_fadt->sleep_status_reg.register_bit_width > 0) { uint8_t value; KASSERT(offset == 0); @@ -1514,7 +1515,8 @@ acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval) * For Hardware-reduced ACPI we also emulate PM1A_STS using * SLEEP_STATUS_REG. */ - if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_STS) { + if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_STS && + sc->sc_fadt->sleep_status_reg.register_bit_width > 0) { uint8_t value = (regval >> 8); KASSERT(offset == 0); @@ -1530,7 +1532,8 @@ acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval) * For Hardware-reduced ACPI we also emulate PM1A_CNT using * SLEEP_CONTROL_REG. */ - if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_CNT) { + if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_CNT && + sc->sc_fadt->sleep_control_reg.register_bit_width > 0) { uint8_t value = (regval >> 8); KASSERT(offset == 0); @@ -1609,10 +1612,6 @@ acpi_map_pmregs(struct acpi_softc *sc) const char *name; int reg; - /* Registers don't exist on Hardware-reduced ACPI. */ - if (sc->sc_hw_reduced) - return; - for (reg = 0; reg < ACPIREG_MAXREG; reg++) { size = 0; access = 0; -- 2.20.1