This series introduces three ACPI devices that are particularly useful for laptop/mobile virtualization:
* Battery * AC adapter * Laptop lid button Link to v3: https://lists.nongnu.org/archive/html/qemu-devel/2025-08/msg04138.html Link to GitHub PR, for ease of review: https://github.com/blochl/qemu/pull/4 Changes in v4: -------------- * Rebased on latest master Based on the feedback on v3: * Documentation patch split: each device is now introduced by a separate documentation patch followed by the code patch. * sysfs/procfs host mirroring removed from the C devices: QEMU no longer reads /sys or /proc directly. The devices are now purely QMP-controlled. A reference Python script is added in scripts/laptop-mirror.py that demonstrates how a management layer can translate host sysfs/procfs state into the QMP commands. * Battery I/O region cleanup: the battery registers are now native DWORD-access only, matching the AML AML_DWORD_ACC field layout. * find_*_device() now reports ambiguity: when more than one matching device is present, QMP returns "More than one X device present". * QAPI cleanups: - Stray blank documentation lines in *-set-state removed. - All the new types and commands carry "Since: 11.1". - The C devices no longer #include "qemu/error-report.h" now that they don't call warn_report(). - battery-set-state now rejects impossible combinations (charging && discharging, charge/discharge without present, out-of-range charge-percent and rate). * I/O port unknown-address handling: the default branches in the ioport_read paths now g_assert_not_reached() instead of logging and returning 0. * Set the devices not hotpluggable. * ISA vs. PCI base: kept ISA. ACPI defines PNP0C0A (battery), ACPI0003 (AC adapter) and PNP0C0D (lid) as namespace devices under \_SB with control methods (_BIF/_BST, _PSR, _LID) - see ACPI 6.5 sections 10.2, 10.3 and 9.4 (https://uefi.org/sites/default/files/resources/ACPI_Spec_6_5_Aug29.pdf). There is no PCI class code defined for any of these in the first place, and no actual laptop puts them on PCI - the signals come out of the embedded controller and surface as fixed-hardware ACPI devices. Guest power-management code matches the same way: Linux uses drivers/acpi/{battery,ac,button}, Windows acpi.sys, macOS and the BSDs follow the same pattern. Making the devices PCI would mean inventing a device class no guest has a driver for. Changes in v3: -------------- * Rebased on latest master * Addressed the v2 review by Igor Mammedov Changes in v2: -------------- Based on the feedback from Philippe Mathieu-Daudé and Michael S. Tsirkin: * Complete redesign with dual-mode operation: - QMP control mode (default): Devices are controlled via QMP commands, providing deterministic behavior essential for migration and CI/testing - Host mirroring mode (opt-in): Original sysfs/procfs monitoring behavior, now disabled by default * Migrated to modern QEMU ACPI architecture: - Devices now implement ACPI_DEV_AML_IF interface - AML generation moved from centralized acpi-build.c to device files * Added a QMP interface: - battery-set-state/query-battery - ac-adapter-set-state/query-ac-adapter - lid-button-set-state/query-lid-button * Documentation improvements: - Converted to .rst format - Added examples for both QMP and "fake" sysfs/procfs testing The dual-mode design ensures these devices are migration-safe and deterministic by default, while still allowing host state mirroring when explicitly requested for desktop use cases. Use cases: ---------- 1. Testing: CI systems can programmatically control power states. 2. Cloud: Expose a virtual battery for usage-based resource limiting. 3. Desktop virtualization: Mirror host laptop state to the guest via the laptop-mirror.py reference script (or a libvirt equivalent). 4. Development: Test power management without physical hardware. Example usage: -------------- # QMP-controlled battery qemu-system-x86_64 -device battery \ -qmp unix:/tmp/qmp.sock,server=on,wait=off # Control via QMP {"execute": "battery-set-state", "arguments": {"state": {"present": true, "charging": false, "discharging": true, "charge-percent": 42, "rate": 500}}} # Or, to mirror host laptop state through QMP: $builddir/run scripts/laptop-mirror.py -s /tmp/qmp.sock The series has been tested with Windows and Linux guests, correctly showing battery status, AC adapter state, and lid button events in guest UIs and triggering appropriate power management actions. Thanks again for the reviews. Leonid. Leonid Bloch (8): hw/acpi: Support extended GPE handling for additional ACPI devices docs/specs: Introduce the QEMU Battery documentation hw/acpi: Introduce the QEMU Battery docs/specs: Introduce the QEMU AC adapter documentation hw/acpi: Introduce the QEMU AC adapter docs/specs: Introduce the QEMU lid button documentation hw/acpi: Introduce the QEMU lid button scripts: Add laptop-mirror reference script MAINTAINERS | 27 ++ docs/specs/acad.rst | 126 ++++++++++ docs/specs/battery.rst | 154 ++++++++++++ docs/specs/button.rst | 131 ++++++++++ docs/specs/index.rst | 3 + docs/tools/index.rst | 1 + docs/tools/laptop-mirror.rst | 82 ++++++ hw/acpi/Kconfig | 12 + hw/acpi/acad-stub.c | 20 ++ hw/acpi/acad.c | 251 ++++++++++++++++++ hw/acpi/battery-stub.c | 20 ++ hw/acpi/battery.c | 364 +++++++++++++++++++++++++++ hw/acpi/button-stub.c | 20 ++ hw/acpi/button.c | 227 +++++++++++++++++ hw/acpi/core.c | 17 +- hw/acpi/meson.build | 6 + hw/acpi/trace-events | 12 + hw/i386/Kconfig | 3 + include/hw/acpi/acad.h | 25 ++ include/hw/acpi/acpi_dev_interface.h | 3 + include/hw/acpi/battery.h | 32 +++ include/hw/acpi/button.h | 23 ++ qapi/acpi.json | 165 ++++++++++++ scripts/laptop-mirror.py | 219 ++++++++++++++++ 24 files changed, 1941 insertions(+), 2 deletions(-) create mode 100644 docs/specs/acad.rst create mode 100644 docs/specs/battery.rst create mode 100644 docs/specs/button.rst create mode 100644 docs/tools/laptop-mirror.rst create mode 100644 hw/acpi/acad-stub.c create mode 100644 hw/acpi/acad.c create mode 100644 hw/acpi/battery-stub.c create mode 100644 hw/acpi/battery.c create mode 100644 hw/acpi/button-stub.c create mode 100644 hw/acpi/button.c create mode 100644 include/hw/acpi/acad.h create mode 100644 include/hw/acpi/battery.h create mode 100644 include/hw/acpi/button.h create mode 100755 scripts/laptop-mirror.py -- 2.54.0
