1*db168561SRoger Pau Monné /*-
2*db168561SRoger Pau Monné * SPDX-License-Identifier: BSD-2-Clause
3*db168561SRoger Pau Monné *
4*db168561SRoger Pau Monné * Copyright (c) 2026 Citrix Systems R&D
5*db168561SRoger Pau Monné * All rights reserved.
6*db168561SRoger Pau Monné *
7*db168561SRoger Pau Monné * Redistribution and use in source and binary forms, with or without
8*db168561SRoger Pau Monné * modification, are permitted provided that the following conditions
9*db168561SRoger Pau Monné * are met:
10*db168561SRoger Pau Monné * 1. Redistributions of source code must retain the above copyright
11*db168561SRoger Pau Monné * notice, this list of conditions and the following disclaimer.
12*db168561SRoger Pau Monné * 2. Redistributions in binary form must reproduce the above copyright
13*db168561SRoger Pau Monné * notice, this list of conditions and the following disclaimer in the
14*db168561SRoger Pau Monné * documentation and/or other materials provided with the distribution.
15*db168561SRoger Pau Monné *
16*db168561SRoger Pau Monné * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*db168561SRoger Pau Monné * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*db168561SRoger Pau Monné * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*db168561SRoger Pau Monné * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*db168561SRoger Pau Monné * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*db168561SRoger Pau Monné * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*db168561SRoger Pau Monné * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*db168561SRoger Pau Monné * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*db168561SRoger Pau Monné * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*db168561SRoger Pau Monné * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*db168561SRoger Pau Monné * SUCH DAMAGE.
27*db168561SRoger Pau Monné */
28*db168561SRoger Pau Monné
29*db168561SRoger Pau Monné #include <sys/cdefs.h>
30*db168561SRoger Pau Monné #include "opt_acpi.h"
31*db168561SRoger Pau Monné #include <sys/param.h>
32*db168561SRoger Pau Monné #include <sys/bus.h>
33*db168561SRoger Pau Monné #include <sys/kernel.h>
34*db168561SRoger Pau Monné #include <sys/kobj.h>
35*db168561SRoger Pau Monné
36*db168561SRoger Pau Monné #include <machine/_inttypes.h>
37*db168561SRoger Pau Monné
38*db168561SRoger Pau Monné #include <contrib/dev/acpica/include/acpi.h>
39*db168561SRoger Pau Monné #include <contrib/dev/acpica/include/accommon.h>
40*db168561SRoger Pau Monné
41*db168561SRoger Pau Monné #include <dev/acpica/acpivar.h>
42*db168561SRoger Pau Monné
43*db168561SRoger Pau Monné #include <xen/xen-os.h>
44*db168561SRoger Pau Monné
prepare_sleep_state(uint8_t state,uint32_t a,uint32_t b,bool ext)45*db168561SRoger Pau Monné static int prepare_sleep_state(uint8_t state, uint32_t a, uint32_t b, bool ext)
46*db168561SRoger Pau Monné {
47*db168561SRoger Pau Monné struct xen_platform_op op = {
48*db168561SRoger Pau Monné .cmd = XENPF_enter_acpi_sleep,
49*db168561SRoger Pau Monné .interface_version = XENPF_INTERFACE_VERSION,
50*db168561SRoger Pau Monné .u.enter_acpi_sleep.val_a = a,
51*db168561SRoger Pau Monné .u.enter_acpi_sleep.val_b = b,
52*db168561SRoger Pau Monné .u.enter_acpi_sleep.sleep_state = state,
53*db168561SRoger Pau Monné .u.enter_acpi_sleep.flags =
54*db168561SRoger Pau Monné ext ? XENPF_ACPI_SLEEP_EXTENDED : 0,
55*db168561SRoger Pau Monné };
56*db168561SRoger Pau Monné int error;
57*db168561SRoger Pau Monné
58*db168561SRoger Pau Monné error = HYPERVISOR_platform_op(&op);
59*db168561SRoger Pau Monné if (error)
60*db168561SRoger Pau Monné printf("Xen notify ACPI sleep failed - "
61*db168561SRoger Pau Monné "State %#x A %#x B %#x: %d\n", state, a, b, error);
62*db168561SRoger Pau Monné
63*db168561SRoger Pau Monné return (error ? error : 1);
64*db168561SRoger Pau Monné }
65*db168561SRoger Pau Monné
init_xen_acpi_sleep(void * arg)66*db168561SRoger Pau Monné static int init_xen_acpi_sleep(void *arg)
67*db168561SRoger Pau Monné {
68*db168561SRoger Pau Monné if (!xen_initial_domain())
69*db168561SRoger Pau Monné return (0);
70*db168561SRoger Pau Monné
71*db168561SRoger Pau Monné acpi_set_prepare_sleep(&prepare_sleep_state);
72*db168561SRoger Pau Monné return (0);
73*db168561SRoger Pau Monné }
74*db168561SRoger Pau Monné
75*db168561SRoger Pau Monné SYSINIT(xen_sleep, SI_SUB_CONFIGURE, SI_ORDER_ANY, init_xen_acpi_sleep, NULL);
76