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


Reply via email to