From nobody Sat May 4 05:42:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500543186193705.8592554036295; Thu, 20 Jul 2017 02:33:06 -0700 (PDT) Received: from localhost ([::1]:36980 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dY7p4-00050S-LW for importer@patchew.org; Thu, 20 Jul 2017 05:32:42 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53368) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dY7oD-0004jb-EI for qemu-devel@nongnu.org; Thu, 20 Jul 2017 05:31:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dY7oB-00030a-N0 for qemu-devel@nongnu.org; Thu, 20 Jul 2017 05:31:49 -0400 Received: from manul.sfritsch.de ([2a01:4f8:172:195f:112::2]:37035) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dY7oB-000306-D1 for qemu-devel@nongnu.org; Thu, 20 Jul 2017 05:31:47 -0400 From: Stefan Fritsch To: qemu-devel@nongnu.org Date: Thu, 20 Jul 2017 11:31:26 +0200 Message-Id: <1500543086-26588-1-git-send-email-sf@sfritsch.de> X-Mailer: git-send-email 2.1.4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a01:4f8:172:195f:112::2 Subject: [Qemu-devel] [PATCH] acpi: Add emulated sleep button X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , "Michael S. Tsirkin" , "Dr. David Alan Gilbert" , Markus Armbruster , Paolo Bonzini , Igor Mammedov , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Stefan Fritsch Add an ACPI sleep button and QMP/HMP commands to trigger it. A sleep button is a so called "fixed hardware feature", which makes it more suitable for putting the system to sleep than a laptop lid, for example. The sleep button is disabled by default (Bit 5 in the FACP flags register set and no button "device" present in SSDT/DSDT). Clearing said bit enables it as a fixed feature device. Signed-off-by: Stefan Fritsch --- hmp-commands.hx | 16 ++++++++++++++++ hmp.c | 5 +++++ hmp.h | 1 + hw/acpi/core.c | 8 ++++++++ hw/acpi/ich9.c | 10 ++++++++++ hw/acpi/piix4.c | 12 ++++++++++++ hw/i386/acpi-build.c | 1 - include/hw/acpi/acpi.h | 2 ++ include/hw/acpi/ich9.h | 1 + include/sysemu/sysemu.h | 2 ++ qapi-schema.json | 12 ++++++++++++ qmp.c | 5 +++++ tests/test-hmp.c | 1 + vl.c | 29 +++++++++++++++++++++++++++++ 14 files changed, 104 insertions(+), 1 deletion(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 1941e19932..8ba4380883 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -638,6 +638,22 @@ Reset the system. ETEXI =20 { + .name =3D "system_sleep", + .args_type =3D "", + .params =3D "", + .help =3D "send ACPI sleep event", + .cmd =3D hmp_system_sleep, + }, + +STEXI +@item system_sleep +@findex system_sleep + +Push the virtual sleep button; if supported the system will enter +an ACPI sleep state. +ETEXI + + { .name =3D "system_powerdown", .args_type =3D "", .params =3D "", diff --git a/hmp.c b/hmp.c index bf1de747d5..b4b584016c 100644 --- a/hmp.c +++ b/hmp.c @@ -1047,6 +1047,11 @@ void hmp_system_reset(Monitor *mon, const QDict *qdi= ct) qmp_system_reset(NULL); } =20 +void hmp_system_sleep(Monitor *mon, const QDict *qdict) +{ + qmp_system_sleep(NULL); +} + void hmp_system_powerdown(Monitor *mon, const QDict *qdict) { qmp_system_powerdown(NULL); diff --git a/hmp.h b/hmp.h index 1ff455295e..15b53de9ed 100644 --- a/hmp.h +++ b/hmp.h @@ -45,6 +45,7 @@ void hmp_info_iothreads(Monitor *mon, const QDict *qdict); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); +void hmp_system_sleep(Monitor *mon, const QDict *qdict); void hmp_system_powerdown(Monitor *mon, const QDict *qdict); void hmp_cpu(Monitor *mon, const QDict *qdict); void hmp_memsave(Monitor *mon, const QDict *qdict); diff --git a/hw/acpi/core.c b/hw/acpi/core.c index 95fcac95a2..2ee64b6878 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -422,6 +422,14 @@ void acpi_pm1_evt_power_down(ACPIREGS *ar) } } =20 +void acpi_pm1_evt_sleep(ACPIREGS *ar) +{ + if (ar->pm1.evt.en & ACPI_BITMASK_SLEEP_BUTTON_ENABLE) { + ar->pm1.evt.sts |=3D ACPI_BITMASK_SLEEP_BUTTON_STATUS; + ar->tmr.update_sci(ar); + } +} + void acpi_pm1_evt_reset(ACPIREGS *ar) { ar->pm1.evt.sts =3D 0; diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index c5d8646abc..3faeab4d2e 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -260,6 +260,14 @@ static void pm_reset(void *opaque) acpi_update_sci(&pm->acpi_regs, pm->irq); } =20 +static void pm_sleep_req(Notifier *n, void *opaque) +{ + ICH9LPCPMRegs *pm =3D container_of(n, ICH9LPCPMRegs, sleep_notifier); + + acpi_pm1_evt_sleep(&pm->acpi_regs); +} + + static void pm_powerdown_req(Notifier *n, void *opaque) { ICH9LPCPMRegs *pm =3D container_of(n, ICH9LPCPMRegs, powerdown_notifie= r); @@ -299,6 +307,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, qemu_register_reset(pm_reset, pm); pm->powerdown_notifier.notify =3D pm_powerdown_req; qemu_register_powerdown_notifier(&pm->powerdown_notifier); + pm->sleep_notifier.notify =3D pm_sleep_req; + qemu_register_sleep_notifier(&pm->sleep_notifier); =20 legacy_acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE); diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index f276967365..15e20976c3 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -79,6 +79,7 @@ typedef struct PIIX4PMState { int smm_enabled; Notifier machine_ready; Notifier powerdown_notifier; + Notifier sleep_notifier; =20 AcpiPciHpState acpi_pci_hotplug; bool use_acpi_pci_hotplug; @@ -371,6 +372,15 @@ static void piix4_pm_powerdown_req(Notifier *n, void *= opaque) acpi_pm1_evt_power_down(&s->ar); } =20 +static void piix4_pm_sleep_req(Notifier *n, void *opaque) +{ + PIIX4PMState *s =3D container_of(n, PIIX4PMState, sleep_notifier); + + assert(s !=3D NULL); + acpi_pm1_evt_sleep(&s->ar); +} + + static void piix4_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -535,6 +545,8 @@ static void piix4_pm_realize(PCIDevice *dev, Error **er= rp) =20 s->powerdown_notifier.notify =3D piix4_pm_powerdown_req; qemu_register_powerdown_notifier(&s->powerdown_notifier); + s->sleep_notifier.notify =3D piix4_pm_sleep_req; + qemu_register_sleep_notifier(&s->sleep_notifier); =20 s->machine_ready.notify =3D piix4_pm_machine_ready; qemu_add_machine_init_done_notifier(&s->machine_ready); diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 6b7bade183..06b28dacfe 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -294,7 +294,6 @@ static void fadt_setup(AcpiFadtDescriptorRev3 *fadt, Ac= piPmInfo *pm) fadt->plvl3_lat =3D cpu_to_le16(0xfff); /* C3 state not supported */ fadt->flags =3D cpu_to_le32((1 << ACPI_FADT_F_WBINVD) | (1 << ACPI_FADT_F_PROC_C1) | - (1 << ACPI_FADT_F_SLP_BUTTON) | (1 << ACPI_FADT_F_RTC_S4)); fadt->flags |=3D cpu_to_le32(1 << ACPI_FADT_F_USE_PLATFORM_CLOCK); /* APIC destination mode ("Flat Logical") has an upper limit of 8 CPUs diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h index 7b3d93cf0d..51cf901ef6 100644 --- a/include/hw/acpi/acpi.h +++ b/include/hw/acpi/acpi.h @@ -78,6 +78,7 @@ #define ACPI_BITMASK_PM1_COMMON_ENABLED ( \ ACPI_BITMASK_RT_CLOCK_ENABLE | \ ACPI_BITMASK_POWER_BUTTON_ENABLE | \ + ACPI_BITMASK_SLEEP_BUTTON_ENABLE | \ ACPI_BITMASK_GLOBAL_LOCK_ENABLE | \ ACPI_BITMASK_TIMER_ENABLE) =20 @@ -148,6 +149,7 @@ void acpi_pm_tmr_reset(ACPIREGS *ar); /* PM1a_EVT: piix and ich9 don't implement PM1b. */ uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar); void acpi_pm1_evt_power_down(ACPIREGS *ar); +void acpi_pm1_evt_sleep(ACPIREGS *ar); void acpi_pm1_evt_reset(ACPIREGS *ar); void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, MemoryRegion *parent); diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index a352c94fde..2073eec168 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -48,6 +48,7 @@ typedef struct ICH9LPCPMRegs { =20 uint32_t pm_io_base; Notifier powerdown_notifier; + Notifier sleep_notifier; =20 bool cpu_hotplug_legacy; AcpiCpuHotplug gpe_cpu; diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index b21369672a..00f54653dc 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -75,6 +75,8 @@ void qemu_register_wakeup_notifier(Notifier *notifier); void qemu_system_shutdown_request(ShutdownCause reason); void qemu_system_powerdown_request(void); void qemu_register_powerdown_notifier(Notifier *notifier); +void qemu_system_sleep_request(void); +void qemu_register_sleep_notifier(Notifier *notifier); void qemu_system_debug_request(void); void qemu_system_vmstop_request(RunState reason); void qemu_system_vmstop_request_prepare(void); diff --git a/qapi-schema.json b/qapi-schema.json index 8b015bee2e..c6ccfcd70f 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2314,6 +2314,18 @@ { 'command': 'system_reset' } =20 ## +# @system_sleep: +# +# Requests that a guest perform a ACPI sleep transition by pushing a virtu= al +# sleep button. +# +# Notes: A guest may or may not respond to this command. This command +# returning does not indicate that a guest has accepted the request= or +# that it has gone to sleep. +## +{ 'command': 'system_sleep' } + +## # @system_powerdown: # # Requests that a guest perform a powerdown operation. diff --git a/qmp.c b/qmp.c index b86201e349..bc1f2e3d7f 100644 --- a/qmp.c +++ b/qmp.c @@ -108,6 +108,11 @@ void qmp_system_reset(Error **errp) qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP); } =20 +void qmp_system_sleep(Error **erp) +{ + qemu_system_sleep_request(); +} + void qmp_system_powerdown(Error **erp) { qemu_system_powerdown_request(); diff --git a/tests/test-hmp.c b/tests/test-hmp.c index d77b3c8710..3fa850bf1e 100644 --- a/tests/test-hmp.c +++ b/tests/test-hmp.c @@ -67,6 +67,7 @@ static const char *hmp_cmds[] =3D { "sum 0 512", "x /8i 0x100", "xp /16x 0", + "system_sleep", NULL }; =20 diff --git a/vl.c b/vl.c index fb6b2efafa..6a0f847dcf 100644 --- a/vl.c +++ b/vl.c @@ -1608,6 +1608,7 @@ static ShutdownCause reset_requested; static ShutdownCause shutdown_requested; static int shutdown_signal; static pid_t shutdown_pid; +static int sleep_requested; static int powerdown_requested; static int debug_requested; static int suspend_requested; @@ -1618,6 +1619,8 @@ static NotifierList suspend_notifiers =3D NOTIFIER_LIST_INITIALIZER(suspend_notifiers); static NotifierList wakeup_notifiers =3D NOTIFIER_LIST_INITIALIZER(wakeup_notifiers); +static NotifierList sleep_notifiers =3D + NOTIFIER_LIST_INITIALIZER(sleep_notifiers); static uint32_t wakeup_reason_mask =3D ~(1 << QEMU_WAKEUP_REASON_NONE); =20 ShutdownCause qemu_shutdown_requested_get(void) @@ -1838,6 +1841,24 @@ static void qemu_system_powerdown(void) notifier_list_notify(&powerdown_notifiers, NULL); } =20 +static void qemu_system_sleep(void) +{ + notifier_list_notify(&sleep_notifiers, NULL); +} + +static int qemu_sleep_requested(void) +{ + int r =3D sleep_requested; + sleep_requested =3D 0; + return r; +} + +void qemu_system_sleep_request(void) +{ + sleep_requested =3D 1; + qemu_notify_event(); +} + void qemu_system_powerdown_request(void) { trace_qemu_system_powerdown_request(); @@ -1850,6 +1871,11 @@ void qemu_register_powerdown_notifier(Notifier *noti= fier) notifier_list_add(&powerdown_notifiers, notifier); } =20 +void qemu_register_sleep_notifier(Notifier *notifier) +{ + notifier_list_add(&sleep_notifiers, notifier); +} + void qemu_system_debug_request(void) { debug_requested =3D 1; @@ -1899,6 +1925,9 @@ static bool main_loop_should_exit(void) if (qemu_powerdown_requested()) { qemu_system_powerdown(); } + if (qemu_sleep_requested()) { + qemu_system_sleep(); + } if (qemu_vmstop_requested(&r)) { vm_stop(r); } --=20 2.11.0