diff options
| author | Roger Pau Monné <royger@FreeBSD.org> | 2026-02-24 20:23:08 +0000 |
|---|---|---|
| committer | Roger Pau Monné <royger@FreeBSD.org> | 2026-02-27 07:39:11 +0000 |
| commit | db16856110cbdbdfdc3c8d44edae1b3a7463198e (patch) | |
| tree | fec2ca6c0df2538465779719ab2c047092940610 /sys/dev | |
| parent | bd758ebac3272f720c051570e043e4bc653dcd48 (diff) | |
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/acpica/Osd/OsdHardware.c | 13 | ||||
| -rw-r--r-- | sys/dev/acpica/acpivar.h | 13 | ||||
| -rw-r--r-- | sys/dev/xen/acpi/xen-acpi.c | 75 |
3 files changed, 101 insertions, 0 deletions
diff --git a/sys/dev/acpica/Osd/OsdHardware.c b/sys/dev/acpica/Osd/OsdHardware.c index fbaf76d2a91a..4252cbc63222 100644 --- a/sys/dev/acpica/Osd/OsdHardware.c +++ b/sys/dev/acpica/Osd/OsdHardware.c @@ -37,6 +37,8 @@ extern int acpi_susp_bounce; +int (*acpi_prepare_sleep)(uint8_t state, uint32_t a, uint32_t b, bool ext); + ACPI_STATUS AcpiOsEnterSleep(UINT8 SleepState, UINT32 RegaValue, UINT32 RegbValue) { @@ -45,6 +47,17 @@ AcpiOsEnterSleep(UINT8 SleepState, UINT32 RegaValue, UINT32 RegbValue) if (acpi_susp_bounce) return (AE_CTRL_TERMINATE); + if (acpi_prepare_sleep != NULL) + { + int ret = acpi_prepare_sleep(SleepState, RegaValue, RegbValue, + ACPI_REDUCED_HARDWARE ? true : AcpiGbl_ReducedHardware); + + if (ret < 0) + return (AE_ERROR); + if (ret > 0) + return (AE_CTRL_TERMINATE); + } + return (AE_OK); } diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index aa8d5bd0971f..b86c6c1aa3c6 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -610,6 +610,19 @@ int acpi_pxm_parse(device_t dev); int acpi_map_pxm_to_vm_domainid(int pxm); bus_get_cpus_t acpi_get_cpus; +/* + * Hook for ACPI sleep routine. + */ +extern int (*acpi_prepare_sleep)(uint8_t state, uint32_t a, uint32_t b, + bool ext); + +static inline void +acpi_set_prepare_sleep( + int (*hook)(uint8_t state, uint32_t a, uint32_t b, bool ext)) +{ + acpi_prepare_sleep = hook; +} + #ifdef __aarch64__ /* * ARM specific ACPI interfaces, relating to IORT table. diff --git a/sys/dev/xen/acpi/xen-acpi.c b/sys/dev/xen/acpi/xen-acpi.c new file mode 100644 index 000000000000..1e46883e2c86 --- /dev/null +++ b/sys/dev/xen/acpi/xen-acpi.c @@ -0,0 +1,75 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 Citrix Systems R&D + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +#include "opt_acpi.h" +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/kobj.h> + +#include <machine/_inttypes.h> + +#include <contrib/dev/acpica/include/acpi.h> +#include <contrib/dev/acpica/include/accommon.h> + +#include <dev/acpica/acpivar.h> + +#include <xen/xen-os.h> + +static int prepare_sleep_state(uint8_t state, uint32_t a, uint32_t b, bool ext) +{ + struct xen_platform_op op = { + .cmd = XENPF_enter_acpi_sleep, + .interface_version = XENPF_INTERFACE_VERSION, + .u.enter_acpi_sleep.val_a = a, + .u.enter_acpi_sleep.val_b = b, + .u.enter_acpi_sleep.sleep_state = state, + .u.enter_acpi_sleep.flags = + ext ? XENPF_ACPI_SLEEP_EXTENDED : 0, + }; + int error; + + error = HYPERVISOR_platform_op(&op); + if (error) + printf("Xen notify ACPI sleep failed - " + "State %#x A %#x B %#x: %d\n", state, a, b, error); + + return (error ? error : 1); +} + +static int init_xen_acpi_sleep(void *arg) +{ + if (!xen_initial_domain()) + return (0); + + acpi_set_prepare_sleep(&prepare_sleep_state); + return (0); +} + +SYSINIT(xen_sleep, SI_SUB_CONFIGURE, SI_ORDER_ANY, init_xen_acpi_sleep, NULL); |
