Hi,

Seems like this patch doesn't build:

FAILED: libqemu-riscv64-softmmu.a.p/hw_riscv_virt.c.o
(...)
../hw/riscv/virt.c
../hw/riscv/virt.c: In function ‘virt_machine_init’:
../hw/riscv/virt.c:1732:9: error: too few arguments to function 
‘virt_is_acpi_enabled’; expected 1, have 0
 1732 |     if (virt_is_acpi_enabled()) {
      |         ^~~~~~~~~~~~~~~~~~~~
In file included from ../hw/riscv/virt.c:37:
/home/danielhb/work/qemu/include/hw/riscv/virt.h:139:6: note: declared here
  139 | bool virt_is_acpi_enabled(RISCVVirtState *s);
      |      ^~~~~~~~~~~~~~~~~~~~
[2211/3002] Compiling C object 
libqemu-riscv64-softmmu.a.p/hw_riscv_virt-acpi-build.c.o
ninja: build stopped: subcommand failed.


This diff fixes it:

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index a4eba9c1bd..5bb1504498 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1729,7 +1729,7 @@ static void virt_machine_init(MachineState *machine)
     create_platform_bus(s, mmio_irqchip);
/* acpi ged */
-    if (virt_is_acpi_enabled()) {
+    if (virt_is_acpi_enabled(s)) {
         s->acpi_ged = create_acpi_ged(s, mmio_irqchip);
     }
After fixing the build, we'll have a failure in 'make check-qtest':


148/336 qemu:qtest+qtest-riscv64 / qtest-riscv64/bios-tables-test           
ERROR           18.20s   killed by signal 6 SIGABRT


This failure happens because you're changing the default bios table without
updating the test. To update it, assuming you're building QEMU in the default
'build' dir:

$ ninja -C build && make -j check-qtest
$ cd build && sh tests/data/acpi/rebuild-expected-aml.sh && cd ..

And then "$ ninja -C build && make -j check-qtest" to confirm that the test is
fixed. Don't forget to add the changes in /tests/data/acpi/riscv64/virt/RHCT
in this patch.


Thanks,

Daniel




On 6/20/25 12:30 AM, liu.xuem...@zte.com.cn wrote:
From: Xuemei Liu <liu.xuem...@zte.com.cn>

This adds powerdown support by implementing the ACPI GED.

Signed-off-by: Xuemei Liu <liu.xuem...@zte.com.cn>
Co-authored-by: Björn Töpel <bj...@rivosinc.com>

---
Changes in v2:
- Unwrappered acpi_dsdt_add_ged function
- Modified base address of VIRT_ACPI_GED
- Added conditions for function calls
- Adjusted code formatting

  hw/riscv/Kconfig           |  1 +
  hw/riscv/virt-acpi-build.c | 10 ++++++++++
  hw/riscv/virt.c            | 35 +++++++++++++++++++++++++++++++++++
  include/hw/riscv/virt.h    |  4 ++++
  4 files changed, 50 insertions(+)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index e6a0ac1fa1..16837e0e8f 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -68,6 +68,7 @@ config RISCV_VIRT
      select PLATFORM_BUS
      select ACPI
      select ACPI_PCI
+    select ACPI_HW_REDUCED

  config SHAKTI_C
      bool
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 8b5683dbde..163533f9b8 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -27,6 +27,7 @@
  #include "hw/acpi/acpi-defs.h"
  #include "hw/acpi/acpi.h"
  #include "hw/acpi/aml-build.h"
+#include "hw/acpi/generic_event_device.h"
  #include "hw/acpi/pci.h"
  #include "hw/acpi/utils.h"
  #include "hw/intc/riscv_aclint.h"
@@ -498,6 +499,15 @@ static void build_dsdt(GArray *table_data,
          acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 
2);
      }

+    if (s->acpi_ged) {
+        build_ged_aml(scope, "\\_SB."GED_DEVICE,
+                      HOTPLUG_HANDLER(s->acpi_ged),
+                      ACPI_GED_IRQ, AML_SYSTEM_MEMORY,
+                      s->memmap[VIRT_ACPI_GED].base);
+    }
+
+    acpi_dsdt_add_power_button(scope);
+
      aml_append(dsdt, scope);

      /* copy AML table into ACPI tables blob and patch header there */
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index cf280a92e5..3e95a49c64 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -51,10 +51,12 @@
  #include "system/kvm.h"
  #include "system/tpm.h"
  #include "system/qtest.h"
+#include "system/runstate.h"
  #include "hw/pci/pci.h"
  #include "hw/pci-host/gpex.h"
  #include "hw/display/ramfb.h"
  #include "hw/acpi/aml-build.h"
+#include "hw/acpi/generic_event_device.h"
  #include "qapi/qapi-visit-common.h"
  #include "hw/virtio/virtio-iommu.h"
  #include "hw/uefi/var-service-api.h"
@@ -95,6 +97,7 @@ static const MemMapEntry virt_memmap[] = {
      [VIRT_UART0] =        { 0x10000000,         0x100 },
      [VIRT_VIRTIO] =       { 0x10001000,        0x1000 },
      [VIRT_FW_CFG] =       { 0x10100000,          0x18 },
+    [VIRT_ACPI_GED] =     { 0x10101000, ACPI_GED_EVT_SEL_LEN },
      [VIRT_FLASH] =        { 0x20000000,     0x4000000 },
      [VIRT_IMSIC_M] =      { 0x24000000, VIRT_IMSIC_MAX_SIZE },
      [VIRT_IMSIC_S] =      { 0x28000000, VIRT_IMSIC_MAX_SIZE },
@@ -1272,6 +1275,22 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion 
*sys_mem,
      return dev;
  }

+static DeviceState *create_acpi_ged(RISCVVirtState *s, DeviceState *irqchip)
+{
+    DeviceState *dev;
+    uint32_t event = ACPI_GED_PWR_DOWN_EVT;
+
+    dev = qdev_new(TYPE_ACPI_GED);
+    qdev_prop_set_uint32(dev, "ged-event", event);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, s->memmap[VIRT_ACPI_GED].base);
+    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
+                       qdev_get_gpio_in(irqchip, ACPI_GED_IRQ));
+
+    return dev;
+}
+
  static FWCfgState *create_fw_cfg(const MachineState *ms, hwaddr base)
  {
      FWCfgState *fw_cfg;
@@ -1430,6 +1449,14 @@ static void virt_build_smbios(RISCVVirtState *s)
      }
  }

+static void virt_powerdown_req(Notifier *notifier, void *opaque)
+{
+    RISCVVirtState *s;
+
+    s = container_of(notifier, RISCVVirtState, powerdown_notifier);
+    acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
+}
+
  static void virt_machine_done(Notifier *notifier, void *data)
  {
      RISCVVirtState *s = container_of(notifier, RISCVVirtState,
@@ -1703,6 +1730,11 @@ static void virt_machine_init(MachineState *machine)

      create_platform_bus(s, mmio_irqchip);

+    /* acpi ged */
+    if (virt_is_acpi_enabled()) {
+        s->acpi_ged = create_acpi_ged(s, mmio_irqchip);
+    }
+
      serial_mm_init(system_memory, s->memmap[VIRT_UART0].base,
          0, qdev_get_gpio_in(mmio_irqchip, UART0_IRQ), 399193,
          serial_hd(0), DEVICE_LITTLE_ENDIAN);
@@ -1744,6 +1776,9 @@ static void virt_machine_init(MachineState *machine)
          sysbus_realize_and_unref(SYS_BUS_DEVICE(iommu_sys), &error_fatal);
      }

+    s->powerdown_notifier.notify = virt_powerdown_req;
+    qemu_register_powerdown_notifier(&s->powerdown_notifier);
+
      s->machine_done.notify = virt_machine_done;
      qemu_add_machine_init_done_notifier(&s->machine_done);
  }
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 7b4c2c8b7d..9422b45d0c 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -47,6 +47,8 @@ struct RISCVVirtState {

      /*< public >*/
      Notifier machine_done;
+    Notifier powerdown_notifier;
+    DeviceState *acpi_ged;
      DeviceState *platform_bus_dev;
      RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
      DeviceState *irqchip[VIRT_SOCKETS_MAX];
@@ -88,9 +90,11 @@ enum {
      VIRT_PLATFORM_BUS,
      VIRT_PCIE_ECAM,
      VIRT_IOMMU_SYS,
+    VIRT_ACPI_GED,
  };

  enum {
+    ACPI_GED_IRQ = 9,
      UART0_IRQ = 10,
      RTC_IRQ = 11,
      VIRTIO_IRQ = 1, /* 1 to 8 */


Reply via email to