The GPE event is triggered to notify the guest to suspend or wakeup itself. This patch removes the previous implementation of QEMU_WAKEUP_REASON_OTHER pretending the resume was caused by power button.
Signed-off-by: Annie Li <annie...@oracle.com> --- hw/acpi/core.c | 17 +++++++++++++---- hw/core/machine-qmp-cmds.c | 2 ++ include/hw/acpi/acpi.h | 1 + include/hw/acpi/acpi_dev_interface.h | 1 + 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/hw/acpi/core.c b/hw/acpi/core.c index ec5e127d17..e5c3ff9a54 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -354,6 +354,16 @@ int acpi_get_slic_oem(AcpiSlicOem *oem) return -1; } +void acpi_send_sleep_wakeup_event(void) +{ + Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, NULL); + + if (obj) { + /* Send _GPE.L07 event */ + acpi_send_event(DEVICE(obj), ACPI_SLEEP_STATUS); + } +} + static void acpi_notify_wakeup(Notifier *notifier, void *data) { ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup); @@ -369,10 +379,9 @@ static void acpi_notify_wakeup(Notifier *notifier, void *data) (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS); break; case QEMU_WAKEUP_REASON_OTHER: - /* ACPI_BITMASK_WAKE_STATUS should be set on resume. - Pretend that resume was caused by power button */ - ar->pm1.evt.sts |= - (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); + /* ACPI_BITMASK_WAKE_STATUS should be set on resume. */ + ar->pm1.evt.sts |= ACPI_BITMASK_WAKE_STATUS; + acpi_send_sleep_wakeup_event(); break; default: break; diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index 9f1e636c90..d51802214b 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -9,6 +9,7 @@ #include "qemu/osdep.h" #include "hw/acpi/vmgenid.h" +#include "hw/acpi/acpi.h" #include "hw/boards.h" #include "hw/intc/intc.h" #include "hw/mem/memory-device.h" @@ -264,6 +265,7 @@ void qmp_system_sleep(Error **errp) "suspend from running is not supported by this guest"); return; } + acpi_send_sleep_wakeup_event(); } void qmp_system_powerdown(Error **errp) diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h index e0e51e85b4..07e31aa138 100644 --- a/include/hw/acpi/acpi.h +++ b/include/hw/acpi/acpi.h @@ -181,6 +181,7 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr); void acpi_send_gpe_event(ACPIREGS *ar, qemu_irq irq, AcpiEventStatusBits status); +void acpi_send_sleep_wakeup_event(void); void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq); diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h index 68d9d15f50..1cb050cd3a 100644 --- a/include/hw/acpi/acpi_dev_interface.h +++ b/include/hw/acpi/acpi_dev_interface.h @@ -13,6 +13,7 @@ typedef enum { ACPI_NVDIMM_HOTPLUG_STATUS = 16, ACPI_VMGENID_CHANGE_STATUS = 32, ACPI_POWER_DOWN_STATUS = 64, + ACPI_SLEEP_STATUS = 128, } AcpiEventStatusBits; #define TYPE_ACPI_DEVICE_IF "acpi-device-interface" -- 2.34.3