qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/22] ACPI PCI Hotplug support on ARM
@ 2025-05-14 17:00 Eric Auger
  2025-05-14 17:00 ` [PATCH 01/22] hw/i386/acpi-build: Make aml_pci_device_dsm() static Eric Auger
                   ` (22 more replies)
  0 siblings, 23 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

This series enables ACPI PCI hotplug/hotunplug on ARM
and makes it default for 10.1 machine type. This aligns with
x86 q35 machine. Expected benefits should be similar to
those listed in [1].

It is still possible to disable it using a virt machine
option: virt,acpi-pcihp=off and restore the legacy behavior.

The infrastructure used in x86 is heavily reused and a
huge part of the series consists in moving code from
hw/i386/acpi-build.c to a generic place and slightly
adapting it to make it usable on ARM. The DSDT table is
augmented to support ACPI PCI hotplug elements.

On ARM we use use a GED event to notify the OS about
hotplug events.

I have not noticed any tests/qtest/bios-tables-test failures
neither on x86 nor ARM. x86 DSDT table has not changed.
ARM DSDT table definitively has but there are no tests
impacted. ARM misses hotplug tests that do exist on x86. This
most probably should be considered in the future.

Best Regards

Eric

This series can be found at:
https://github.com/eauger/qemu/tree/arm-acpi-pcihp-v1

previous RFC:
https://github.com/eauger/qemu/tree/arm-acpi-pcihp-rfc

History:
RFC -> v1:
- First 3 trivial patches were pulled separately
- Fix of the register region size (0x18), ie. ACPI_PCIHP_SIZE
- addition of aml_pci_edsm which was not called in RFC
- acpi-index feature is now fixed. vms->bus was not set on
  acpi_pcihp_init. The init sequence is still hacky though. Suggestions
  appreciated.

[1] [PATCH v6 0/6] Use ACPI PCI hot-plug for Q35
https://lore.kernel.org/all/20210713004205.775386-1-jusual@redhat.com/


Eric Auger (22):
  hw/i386/acpi-build: Make aml_pci_device_dsm() static
  hw/arm/virt: Introduce machine state acpi pcihp flags and props
  hw/acpi: Rename and move build_x86_acpi_pci_hotplug to pcihp
  hw/pci-host/gpex-acpi: Add native_pci_hotplug arg to
    acpi_dsdt_add_pci_osc
  hw/pci-host/gpex-acpi: Split host bridge OSC and DSM generation
  hw/pci-host/gpex-acpi: Propagate hotplug type info from virt machine
    downto gpex
  hw/i386/acpi-build: Turn build_q35_osc_method into a generic method
  hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method
  hw/i386/acpi-build: Introduce build_append_pcihp_resources() helper
  hw/acpi/pcihp: Add an AmlRegionSpace arg to build_acpi_pci_hotplug
  hw/i386/acpi-build: Move build_append_notification_callback to pcihp
  hw/i386/acpi-build: Move build_append_pci_bus_devices/pcihp_slots to
    pcihp
  hw/i386/acpi-build: Introduce and use acpi_get_pci_host
  hw/i386/acpi-build: Move aml_pci_edsm to a generic place
  hw/arm/virt-acpi-build: Modify the DSDT ACPI table to enable ACPI PCI
    hotplug
  hw/acpi/ged: Prepare the device to react to PCI hotplug events
  hw/acpi/ged: Call pcihp plug callbacks in hotplug handler
    implementation
  hw/acpi/ged: Support migration of AcpiPciHpState
  hw/core/sysbus: Introduce sysbus_mmio_map_name() helper
  hw/arm/virt: Let virt support pci hotplug/unplug GED event
  hw/arm/virt: Plug pcihp hotplug/hotunplug callbacks
  hw/arm/virt: Use ACPI PCI hotplug by default

 hw/i386/acpi-build.h                   |   4 -
 include/hw/acpi/aml-build.h            |   2 +
 include/hw/acpi/generic_event_device.h |   5 +
 include/hw/acpi/pci.h                  |   4 +-
 include/hw/acpi/pcihp.h                |  19 +-
 include/hw/arm/virt.h                  |   4 +
 include/hw/pci-host/gpex.h             |   1 +
 include/hw/sysbus.h                    |   1 +
 hw/acpi/aml-build.c                    |  50 +++
 hw/acpi/generic_event_device.c         |  55 +++
 hw/acpi/pci.c                          |  20 +
 hw/acpi/pcihp.c                        | 482 ++++++++++++++++++++-
 hw/arm/virt-acpi-build.c               |  27 ++
 hw/arm/virt.c                          | 107 ++++-
 hw/core/sysbus.c                       |  11 +
 hw/i386/acpi-build.c                   | 552 +------------------------
 hw/pci-host/gpex-acpi.c                |  75 +---
 hw/arm/Kconfig                         |   2 +
 18 files changed, 806 insertions(+), 615 deletions(-)

-- 
2.49.0



^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH 01/22] hw/i386/acpi-build: Make aml_pci_device_dsm() static
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-20 12:30   ` Gustavo Romero
  2025-05-25 15:29   ` Philippe Mathieu-Daudé
  2025-05-14 17:00 ` [PATCH 02/22] hw/arm/virt: Introduce machine state acpi pcihp flags and props Eric Auger
                   ` (21 subsequent siblings)
  22 siblings, 2 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

No need to export aml_pci_device_dsm() as it is only used
in hw/i386/acpi-build.c.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/acpi/pci.h | 1 -
 hw/i386/acpi-build.c  | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h
index 6359d574fd..ab0187a894 100644
--- a/include/hw/acpi/pci.h
+++ b/include/hw/acpi/pci.h
@@ -36,7 +36,6 @@ typedef struct AcpiMcfgInfo {
 
 void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info,
                 const char *oem_id, const char *oem_table_id);
-Aml *aml_pci_device_dsm(void);
 
 void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
 void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope);
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index f40ad062f9..9e584e69fd 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -338,7 +338,7 @@ build_facs(GArray *table_data)
     g_array_append_vals(table_data, reserved, 40); /* Reserved */
 }
 
-Aml *aml_pci_device_dsm(void)
+static Aml *aml_pci_device_dsm(void)
 {
     Aml *method;
 
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 02/22] hw/arm/virt: Introduce machine state acpi pcihp flags and props
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
  2025-05-14 17:00 ` [PATCH 01/22] hw/i386/acpi-build: Make aml_pci_device_dsm() static Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-14 17:00 ` [PATCH 03/22] hw/acpi: Rename and move build_x86_acpi_pci_hotplug to pcihp Eric Auger
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

acpi_pcihp VirtMachineClass state flag will allow
to opt in for acpi pci hotplug. This is guarded by a
class no_acpi_pcihp flag to manage compats (<= 10.0
machine types will not support ACPI PCI hotplug).

Machine state acpi_pcihp flag must be set before the creation
of the GED device which will use it.

Currently the ACPI PCI HP is turned off by default. This will
change later on for 10.1 machine type.

We also introduce properties to allow disabling it.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>
---
 include/hw/arm/virt.h |  2 ++
 hw/arm/virt.c         | 27 +++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 9a1b0f53d2..10ea581f06 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -129,6 +129,7 @@ struct VirtMachineClass {
     bool no_tcg_lpa2;
     bool no_ns_el2_virt_timer_irq;
     bool no_nested_smmu;
+    bool no_acpi_pcihp;
 };
 
 struct VirtMachineState {
@@ -150,6 +151,7 @@ struct VirtMachineState {
     bool mte;
     bool dtb_randomness;
     bool second_ns_uart_present;
+    bool acpi_pcihp;
     OnOffAuto acpi;
     VirtGICType gic_version;
     VirtIOMMUType iommu;
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 9a6cd085a3..a0deeaf2b3 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2397,8 +2397,10 @@ static void machvirt_init(MachineState *machine)
     create_pcie(vms);
 
     if (has_ged && aarch64 && firmware_loaded && virt_is_acpi_enabled(vms)) {
+        vms->acpi_pcihp &= !vmc->no_acpi_pcihp;
         vms->acpi_dev = create_acpi_ged(vms);
     } else {
+        vms->acpi_pcihp = false;
         create_gpio_devices(vms, VIRT_GPIO, sysmem);
     }
 
@@ -2593,6 +2595,20 @@ static void virt_set_its(Object *obj, bool value, Error **errp)
     vms->its = value;
 }
 
+static bool virt_get_acpi_pcihp(Object *obj, Error **errp)
+{
+    VirtMachineState *vms = VIRT_MACHINE(obj);
+
+    return vms->acpi_pcihp;
+}
+
+static void virt_set_acpi_pcihp(Object *obj, bool value, Error **errp)
+{
+    VirtMachineState *vms = VIRT_MACHINE(obj);
+
+    vms->acpi_pcihp = value;
+}
+
 static bool virt_get_dtb_randomness(Object *obj, Error **errp)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -3310,6 +3326,10 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
                                           "in ACPI table header."
                                           "The string may be up to 8 bytes in size");
 
+    object_class_property_add_bool(oc, "acpi-pcihp",
+                                   virt_get_acpi_pcihp, virt_set_acpi_pcihp);
+    object_class_property_set_description(oc, "acpi-pcihp",
+                                          "Force ACPI PCI hotplug");
 }
 
 static void virt_instance_init(Object *obj)
@@ -3344,6 +3364,9 @@ static void virt_instance_init(Object *obj)
         vms->tcg_its = true;
     }
 
+    /* default disallows ACPI PCI hotplug */
+    vms->acpi_pcihp = false;
+
     /* Default disallows iommu instantiation */
     vms->iommu = VIRT_IOMMU_NONE;
 
@@ -3394,8 +3417,12 @@ DEFINE_VIRT_MACHINE_AS_LATEST(10, 1)
 
 static void virt_machine_10_0_options(MachineClass *mc)
 {
+    VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
     virt_machine_10_1_options(mc);
     compat_props_add(mc->compat_props, hw_compat_10_0, hw_compat_10_0_len);
+    /* 10.0 and earlier do not support ACPI PCI hotplug */
+    vmc->no_acpi_pcihp = true;
 }
 DEFINE_VIRT_MACHINE(10, 0)
 
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 03/22] hw/acpi: Rename and move build_x86_acpi_pci_hotplug to pcihp
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
  2025-05-14 17:00 ` [PATCH 01/22] hw/i386/acpi-build: Make aml_pci_device_dsm() static Eric Auger
  2025-05-14 17:00 ` [PATCH 02/22] hw/arm/virt: Introduce machine state acpi pcihp flags and props Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-20 12:31   ` Gustavo Romero
  2025-05-14 17:00 ` [PATCH 04/22] hw/pci-host/gpex-acpi: Add native_pci_hotplug arg to acpi_dsdt_add_pci_osc Eric Auger
                   ` (19 subsequent siblings)
  22 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

We plan to reuse build_x86_acpi_pci_hotplug() implementation
for ARM so let's move the code to generic pcihp.

Associated static aml_pci_pdsm() helper is also moved along.
build_x86_acpi_pci_hotplug is renamed into build_acpi_pci_hotplug().

No code change intended.

Also fix the reference to  acpi_pci_hotplug.rst documentation

Signed-off-by: Eric Auger <eric.auger@redhat.com>

---

rfc -> v1:
- make build_append_pci_dsm_func0_common non static and move it to
  pcihp
---
 hw/i386/acpi-build.h    |   4 -
 include/hw/acpi/pcihp.h |   9 +-
 hw/acpi/pcihp.c         | 174 ++++++++++++++++++++++++++++++++++++++-
 hw/i386/acpi-build.c    | 176 +---------------------------------------
 4 files changed, 183 insertions(+), 180 deletions(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 275ec058a1..8ba3c33e48 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -5,10 +5,6 @@
 
 extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 
-/* PCI Hot-plug registers' base. See docs/specs/acpi_pci_hotplug.rst */
-#define ACPI_PCIHP_SEJ_BASE 0x8
-#define ACPI_PCIHP_BNMR_BASE 0x10
-
 void acpi_setup(void);
 Object *acpi_get_i386_pci_host(void);
 
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index a97904bada..95efe9a804 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -3,7 +3,7 @@
  *
  * QEMU supports PCI hotplug via ACPI. This module
  * implements the interface between QEMU and the ACPI BIOS.
- * Interface specification - see docs/specs/acpi_pci_hotplug.txt
+ * Interface specification - see docs/specs/acpi_pci_hotplug.rst
  *
  * Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)
  * Copyright (c) 2006 Fabrice Bellard
@@ -33,6 +33,10 @@
 #define ACPI_PCIHP_IO_BASE_PROP "acpi-pcihp-io-base"
 #define ACPI_PCIHP_IO_LEN_PROP "acpi-pcihp-io-len"
 
+/* PCI Hot-plug registers bases. See docs/spec/acpi_pci_hotplug.rst */
+#define ACPI_PCIHP_SEJ_BASE 0x8
+#define ACPI_PCIHP_BNMR_BASE 0x10
+
 typedef struct AcpiPciHpPciStatus {
     uint32_t up;
     uint32_t down;
@@ -69,6 +73,9 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
                                          AcpiPciHpState *s, DeviceState *dev,
                                          Error **errp);
 
+void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr);
+void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar);
+
 /* Called on reset */
 void acpi_pcihp_reset(AcpiPciHpState *s);
 
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index aac90013d4..e0260f67e6 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -26,7 +26,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/acpi/pcihp.h"
-
+#include "hw/acpi/aml-build.h"
 #include "hw/pci-host/i440fx.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bridge.h"
@@ -513,6 +513,178 @@ void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
                                    OBJ_PROP_FLAG_READ);
 }
 
+void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar)
+{
+    Aml *UUID, *ifctx1;
+    uint8_t byte_list[1] = { 0 }; /* nothing supported yet */
+
+    aml_append(ctx, aml_store(aml_buffer(1, byte_list), retvar));
+    /*
+     * PCI Firmware Specification 3.1
+     * 4.6.  _DSM Definitions for PCI
+     */
+    UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
+    ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(0), UUID)));
+    {
+        /* call is for unsupported UUID, bail out */
+        aml_append(ifctx1, aml_return(retvar));
+    }
+    aml_append(ctx, ifctx1);
+
+    ifctx1 = aml_if(aml_lless(aml_arg(1), aml_int(2)));
+    {
+        /* call is for unsupported REV, bail out */
+        aml_append(ifctx1, aml_return(retvar));
+    }
+    aml_append(ctx, ifctx1);
+}
+
+static Aml *aml_pci_pdsm(void)
+{
+    Aml *method, *ifctx, *ifctx1;
+    Aml *ret = aml_local(0);
+    Aml *caps = aml_local(1);
+    Aml *acpi_index = aml_local(2);
+    Aml *zero = aml_int(0);
+    Aml *one = aml_int(1);
+    Aml *not_supp = aml_int(0xFFFFFFFF);
+    Aml *func = aml_arg(2);
+    Aml *params = aml_arg(4);
+    Aml *bnum = aml_derefof(aml_index(params, aml_int(0)));
+    Aml *sunum = aml_derefof(aml_index(params, aml_int(1)));
+
+    method = aml_method("PDSM", 5, AML_SERIALIZED);
+
+    /* get supported functions */
+    ifctx = aml_if(aml_equal(func, zero));
+    {
+        build_append_pci_dsm_func0_common(ifctx, ret);
+
+        aml_append(ifctx, aml_store(zero, caps));
+        aml_append(ifctx,
+            aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
+        /*
+         * advertise function 7 if device has acpi-index
+         * acpi_index values:
+         *            0: not present (default value)
+         *     FFFFFFFF: not supported (old QEMU without PIDX reg)
+         *        other: device's acpi-index
+         */
+        ifctx1 = aml_if(aml_lnot(
+                     aml_or(aml_equal(acpi_index, zero),
+                            aml_equal(acpi_index, not_supp), NULL)
+                 ));
+        {
+            /* have supported functions */
+            aml_append(ifctx1, aml_or(caps, one, caps));
+            /* support for function 7 */
+            aml_append(ifctx1,
+                aml_or(caps, aml_shiftleft(one, aml_int(7)), caps));
+        }
+        aml_append(ifctx, ifctx1);
+
+        aml_append(ifctx, aml_store(caps, aml_index(ret, zero)));
+        aml_append(ifctx, aml_return(ret));
+    }
+    aml_append(method, ifctx);
+
+    /* handle specific functions requests */
+    /*
+     * PCI Firmware Specification 3.1
+     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
+     *        Operating Systems
+     */
+    ifctx = aml_if(aml_equal(func, aml_int(7)));
+    {
+       Aml *pkg = aml_package(2);
+
+       aml_append(ifctx, aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
+       aml_append(ifctx, aml_store(pkg, ret));
+       /*
+        * Windows calls func=7 without checking if it's available,
+        * as workaround Microsoft has suggested to return invalid for func7
+        * Package, so return 2 elements package but only initialize elements
+        * when acpi_index is supported and leave them uninitialized, which
+        * leads elements to being Uninitialized ObjectType and should trip
+        * Windows into discarding result as an unexpected and prevent setting
+        * bogus 'PCI Label' on the device.
+        */
+       ifctx1 = aml_if(aml_lnot(aml_lor(
+                    aml_equal(acpi_index, zero), aml_equal(acpi_index, not_supp)
+                )));
+       {
+           aml_append(ifctx1, aml_store(acpi_index, aml_index(ret, zero)));
+           /*
+            * optional, if not impl. should return null string
+            */
+           aml_append(ifctx1, aml_store(aml_string("%s", ""),
+                                        aml_index(ret, one)));
+       }
+       aml_append(ifctx, ifctx1);
+
+       aml_append(ifctx, aml_return(ret));
+    }
+
+    aml_append(method, ifctx);
+    return method;
+}
+
+void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr)
+{
+    Aml *scope;
+    Aml *field;
+    Aml *method;
+
+    scope =  aml_scope("_SB.PCI0");
+
+    aml_append(scope,
+        aml_operation_region("PCST", AML_SYSTEM_IO, aml_int(pcihp_addr), 0x08));
+    field = aml_field("PCST", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
+    aml_append(field, aml_named_field("PCIU", 32));
+    aml_append(field, aml_named_field("PCID", 32));
+    aml_append(scope, field);
+
+    aml_append(scope,
+        aml_operation_region("SEJ", AML_SYSTEM_IO,
+                             aml_int(pcihp_addr + ACPI_PCIHP_SEJ_BASE), 0x04));
+    field = aml_field("SEJ", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
+    aml_append(field, aml_named_field("B0EJ", 32));
+    aml_append(scope, field);
+
+    aml_append(scope,
+        aml_operation_region("BNMR", AML_SYSTEM_IO,
+                             aml_int(pcihp_addr + ACPI_PCIHP_BNMR_BASE), 0x08));
+    field = aml_field("BNMR", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
+    aml_append(field, aml_named_field("BNUM", 32));
+    aml_append(field, aml_named_field("PIDX", 32));
+    aml_append(scope, field);
+
+    aml_append(scope, aml_mutex("BLCK", 0));
+
+        method = aml_method("PCEJ", 2, AML_NOTSERIALIZED);
+    aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
+    aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
+    aml_append(method,
+        aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("B0EJ")));
+    aml_append(method, aml_release(aml_name("BLCK")));
+    aml_append(method, aml_return(aml_int(0)));
+    aml_append(scope, method);
+
+    method = aml_method("AIDX", 2, AML_NOTSERIALIZED);
+    aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
+    aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
+    aml_append(method,
+        aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("PIDX")));
+    aml_append(method, aml_store(aml_name("PIDX"), aml_local(0)));
+    aml_append(method, aml_release(aml_name("BLCK")));
+    aml_append(method, aml_return(aml_local(0)));
+    aml_append(scope, method);
+
+    aml_append(scope, aml_pci_pdsm());
+
+    aml_append(table, scope);
+}
+
 const VMStateDescription vmstate_acpi_pcihp_pci_status = {
     .name = "acpi_pcihp_pci_status",
     .version_id = 1,
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 9e584e69fd..b92765fbd9 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -361,32 +361,6 @@ static Aml *aml_pci_device_dsm(void)
     return method;
 }
 
-static void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar)
-{
-    Aml *UUID, *ifctx1;
-    uint8_t byte_list[1] = { 0 }; /* nothing supported yet */
-
-    aml_append(ctx, aml_store(aml_buffer(1, byte_list), retvar));
-    /*
-     * PCI Firmware Specification 3.1
-     * 4.6.  _DSM Definitions for PCI
-     */
-    UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
-    ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(0), UUID)));
-    {
-        /* call is for unsupported UUID, bail out */
-        aml_append(ifctx1, aml_return(retvar));
-    }
-    aml_append(ctx, ifctx1);
-
-    ifctx1 = aml_if(aml_lless(aml_arg(1), aml_int(2)));
-    {
-        /* call is for unsupported REV, bail out */
-        aml_append(ifctx1, aml_return(retvar));
-    }
-    aml_append(ctx, ifctx1);
-}
-
 static Aml *aml_pci_edsm(void)
 {
     Aml *method, *ifctx;
@@ -647,96 +621,6 @@ static bool build_append_notification_callback(Aml *parent_scope,
     return !!nr_notifiers;
 }
 
-static Aml *aml_pci_pdsm(void)
-{
-    Aml *method, *ifctx, *ifctx1;
-    Aml *ret = aml_local(0);
-    Aml *caps = aml_local(1);
-    Aml *acpi_index = aml_local(2);
-    Aml *zero = aml_int(0);
-    Aml *one = aml_int(1);
-    Aml *not_supp = aml_int(0xFFFFFFFF);
-    Aml *func = aml_arg(2);
-    Aml *params = aml_arg(4);
-    Aml *bnum = aml_derefof(aml_index(params, aml_int(0)));
-    Aml *sunum = aml_derefof(aml_index(params, aml_int(1)));
-
-    method = aml_method("PDSM", 5, AML_SERIALIZED);
-
-    /* get supported functions */
-    ifctx = aml_if(aml_equal(func, zero));
-    {
-        build_append_pci_dsm_func0_common(ifctx, ret);
-
-        aml_append(ifctx, aml_store(zero, caps));
-        aml_append(ifctx,
-            aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
-        /*
-         * advertise function 7 if device has acpi-index
-         * acpi_index values:
-         *            0: not present (default value)
-         *     FFFFFFFF: not supported (old QEMU without PIDX reg)
-         *        other: device's acpi-index
-         */
-        ifctx1 = aml_if(aml_lnot(
-                     aml_or(aml_equal(acpi_index, zero),
-                            aml_equal(acpi_index, not_supp), NULL)
-                 ));
-        {
-            /* have supported functions */
-            aml_append(ifctx1, aml_or(caps, one, caps));
-            /* support for function 7 */
-            aml_append(ifctx1,
-                aml_or(caps, aml_shiftleft(one, aml_int(7)), caps));
-        }
-        aml_append(ifctx, ifctx1);
-
-        aml_append(ifctx, aml_store(caps, aml_index(ret, zero)));
-        aml_append(ifctx, aml_return(ret));
-    }
-    aml_append(method, ifctx);
-
-    /* handle specific functions requests */
-    /*
-     * PCI Firmware Specification 3.1
-     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
-     *        Operating Systems
-     */
-    ifctx = aml_if(aml_equal(func, aml_int(7)));
-    {
-       Aml *pkg = aml_package(2);
-
-       aml_append(ifctx, aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
-       aml_append(ifctx, aml_store(pkg, ret));
-       /*
-        * Windows calls func=7 without checking if it's available,
-        * as workaround Microsoft has suggested to return invalid for func7
-        * Package, so return 2 elements package but only initialize elements
-        * when acpi_index is supported and leave them uninitialized, which
-        * leads elements to being Uninitialized ObjectType and should trip
-        * Windows into discarding result as an unexpected and prevent setting
-        * bogus 'PCI Label' on the device.
-        */
-       ifctx1 = aml_if(aml_lnot(aml_lor(
-                    aml_equal(acpi_index, zero), aml_equal(acpi_index, not_supp)
-                )));
-       {
-           aml_append(ifctx1, aml_store(acpi_index, aml_index(ret, zero)));
-           /*
-            * optional, if not impl. should return null string
-            */
-           aml_append(ifctx1, aml_store(aml_string("%s", ""),
-                                        aml_index(ret, one)));
-       }
-       aml_append(ifctx, ifctx1);
-
-       aml_append(ifctx, aml_return(ret));
-    }
-
-    aml_append(method, ifctx);
-    return method;
-}
-
 /*
  * build_prt - Define interrupt routing rules
  *
@@ -1227,62 +1111,6 @@ static Aml *build_q35_dram_controller(const AcpiMcfgInfo *mcfg)
     return dev;
 }
 
-static void build_x86_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr)
-{
-    Aml *scope;
-    Aml *field;
-    Aml *method;
-
-    scope =  aml_scope("_SB.PCI0");
-
-    aml_append(scope,
-        aml_operation_region("PCST", AML_SYSTEM_IO, aml_int(pcihp_addr), 0x08));
-    field = aml_field("PCST", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
-    aml_append(field, aml_named_field("PCIU", 32));
-    aml_append(field, aml_named_field("PCID", 32));
-    aml_append(scope, field);
-
-    aml_append(scope,
-        aml_operation_region("SEJ", AML_SYSTEM_IO,
-                             aml_int(pcihp_addr + ACPI_PCIHP_SEJ_BASE), 0x04));
-    field = aml_field("SEJ", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
-    aml_append(field, aml_named_field("B0EJ", 32));
-    aml_append(scope, field);
-
-    aml_append(scope,
-        aml_operation_region("BNMR", AML_SYSTEM_IO,
-                             aml_int(pcihp_addr + ACPI_PCIHP_BNMR_BASE), 0x08));
-    field = aml_field("BNMR", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
-    aml_append(field, aml_named_field("BNUM", 32));
-    aml_append(field, aml_named_field("PIDX", 32));
-    aml_append(scope, field);
-
-    aml_append(scope, aml_mutex("BLCK", 0));
-
-    method = aml_method("PCEJ", 2, AML_NOTSERIALIZED);
-    aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
-    aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
-    aml_append(method,
-        aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("B0EJ")));
-    aml_append(method, aml_release(aml_name("BLCK")));
-    aml_append(method, aml_return(aml_int(0)));
-    aml_append(scope, method);
-
-    method = aml_method("AIDX", 2, AML_NOTSERIALIZED);
-    aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
-    aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
-    aml_append(method,
-        aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("PIDX")));
-    aml_append(method, aml_store(aml_name("PIDX"), aml_local(0)));
-    aml_append(method, aml_release(aml_name("BLCK")));
-    aml_append(method, aml_return(aml_local(0)));
-    aml_append(scope, method);
-
-    aml_append(scope, aml_pci_pdsm());
-
-    aml_append(table, scope);
-}
-
 static Aml *build_q35_osc_method(bool enable_native_pcie_hotplug)
 {
     Aml *if_ctx;
@@ -1394,7 +1222,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
         aml_append(dsdt, sb_scope);
 
         if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
-            build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
+            build_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
         }
         build_piix4_pci0_int(dsdt);
     } else if (q35) {
@@ -1438,7 +1266,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
         aml_append(dsdt, sb_scope);
 
         if (pm->pcihp_bridge_en) {
-            build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
+            build_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
         }
         build_q35_pci0_int(dsdt);
     }
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 04/22] hw/pci-host/gpex-acpi: Add native_pci_hotplug arg to acpi_dsdt_add_pci_osc
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (2 preceding siblings ...)
  2025-05-14 17:00 ` [PATCH 03/22] hw/acpi: Rename and move build_x86_acpi_pci_hotplug to pcihp Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-14 17:00 ` [PATCH 05/22] hw/pci-host/gpex-acpi: Split host bridge OSC and DSM generation Eric Auger
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Add a new argument to acpi_dsdt_add_pci_osc to be able to disable
native pci hotplug.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>

---

rfc -> v1:
- updated the "Allow OS control for all 5 features" comment
---
 hw/pci-host/gpex-acpi.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index 0aba47c71c..f34b7cf25e 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -50,7 +50,7 @@ static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq,
     }
 }
 
-static void acpi_dsdt_add_pci_osc(Aml *dev)
+static void acpi_dsdt_add_pci_osc(Aml *dev, bool enable_native_pcie_hotplug)
 {
     Aml *method, *UUID, *ifctx, *ifctx1, *elsectx, *buf;
 
@@ -77,11 +77,12 @@ static void acpi_dsdt_add_pci_osc(Aml *dev)
     aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
 
     /*
-     * Allow OS control for all 5 features:
-     * PCIeHotplug SHPCHotplug PME AER PCIeCapability.
+     * Allow OS control for SHPCHotplug, PME, AER, PCIeCapability,
+     * and PCIeHotplug depending on enable_native_pcie_hotplug
      */
-    aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F),
-                              aml_name("CTRL")));
+    aml_append(ifctx, aml_and(aml_name("CTRL"),
+               aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)),
+               aml_name("CTRL")));
 
     ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
     aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
@@ -192,7 +193,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
             if (is_cxl) {
                 build_cxl_osc_method(dev);
             } else {
-                acpi_dsdt_add_pci_osc(dev);
+                acpi_dsdt_add_pci_osc(dev, true);
             }
 
             aml_append(scope, dev);
@@ -267,7 +268,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
     }
     aml_append(dev, aml_name_decl("_CRS", rbuf));
 
-    acpi_dsdt_add_pci_osc(dev);
+    acpi_dsdt_add_pci_osc(dev, true);
 
     Aml *dev_res0 = aml_device("%s", "RES0");
     aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02")));
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 05/22] hw/pci-host/gpex-acpi: Split host bridge OSC and DSM generation
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (3 preceding siblings ...)
  2025-05-14 17:00 ` [PATCH 04/22] hw/pci-host/gpex-acpi: Add native_pci_hotplug arg to acpi_dsdt_add_pci_osc Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-14 17:00 ` [PATCH 06/22] hw/pci-host/gpex-acpi: Propagate hotplug type info from virt machine downto gpex Eric Auger
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

acpi_dsdt_add_pci_osc() name is confusing as it gives the impression
it appends the _OSC method but in fact it also appends the _DSM method
for the host bridge. Let's split the function into two separate ones
and let them return the method Aml pointer instead. This matches the
way it is done on x86 (build_q35_osc_method). In a subsequent patch
we will replace the gpex method by the q35 implementation that will
become shared between ARM and x86.

acpi_dsdt_add_host_bridge_methods is a new top helper that generates
both the _OSC and _DSM methods.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>
---
 hw/pci-host/gpex-acpi.c | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index f34b7cf25e..1aa2d12026 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -50,13 +50,10 @@ static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq,
     }
 }
 
-static void acpi_dsdt_add_pci_osc(Aml *dev, bool enable_native_pcie_hotplug)
+static Aml *build_host_bridge_osc(bool enable_native_pcie_hotplug)
 {
-    Aml *method, *UUID, *ifctx, *ifctx1, *elsectx, *buf;
+    Aml *method, *UUID, *ifctx, *ifctx1, *elsectx;
 
-    /* Declare an _OSC (OS Control Handoff) method */
-    aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
-    aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
     method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
     aml_append(method,
         aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
@@ -103,9 +100,13 @@ static void acpi_dsdt_add_pci_osc(Aml *dev, bool enable_native_pcie_hotplug)
                                aml_name("CDW1")));
     aml_append(elsectx, aml_return(aml_arg(3)));
     aml_append(method, elsectx);
-    aml_append(dev, method);
+    return method;
+}
 
-    method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
+static Aml *build_host_bridge_dsm(void)
+{
+    Aml *method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
+    Aml *UUID, *ifctx, *ifctx1, *buf;
 
     /* PCI Firmware Specification 3.0
      * 4.6.1. _DSM for PCI Express Slot Information
@@ -124,7 +125,17 @@ static void acpi_dsdt_add_pci_osc(Aml *dev, bool enable_native_pcie_hotplug)
     byte_list[0] = 0;
     buf = aml_buffer(1, byte_list);
     aml_append(method, aml_return(buf));
-    aml_append(dev, method);
+    return method;
+}
+
+static void acpi_dsdt_add_host_bridge_methods(Aml *dev,
+                                              bool enable_native_pcie_hotplug)
+{
+    aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
+    aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
+    /* Declare an _OSC (OS Control Handoff) method */
+    aml_append(dev, build_host_bridge_osc(enable_native_pcie_hotplug));
+    aml_append(dev, build_host_bridge_dsm());
 }
 
 void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
@@ -193,7 +204,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
             if (is_cxl) {
                 build_cxl_osc_method(dev);
             } else {
-                acpi_dsdt_add_pci_osc(dev, true);
+                acpi_dsdt_add_host_bridge_methods(dev, true);
             }
 
             aml_append(scope, dev);
@@ -268,7 +279,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
     }
     aml_append(dev, aml_name_decl("_CRS", rbuf));
 
-    acpi_dsdt_add_pci_osc(dev, true);
+    acpi_dsdt_add_host_bridge_methods(dev, true);
 
     Aml *dev_res0 = aml_device("%s", "RES0");
     aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02")));
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 06/22] hw/pci-host/gpex-acpi: Propagate hotplug type info from virt machine downto gpex
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (4 preceding siblings ...)
  2025-05-14 17:00 ` [PATCH 05/22] hw/pci-host/gpex-acpi: Split host bridge OSC and DSM generation Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-14 17:00 ` [PATCH 07/22] hw/i386/acpi-build: Turn build_q35_osc_method into a generic method Eric Auger
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Propagate the type of pci hotplug mode downto the gpex
acpi code. In case machine acpi_pcihp is unset we configure
pci native hotplug on pci0. For expander bridges we keep
legacy pci native hotplug, as done on x86 q35.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>
---
 include/hw/pci-host/gpex.h | 1 +
 hw/arm/virt-acpi-build.c   | 1 +
 hw/pci-host/gpex-acpi.c    | 3 ++-
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h
index 84471533af..feaf827474 100644
--- a/include/hw/pci-host/gpex.h
+++ b/include/hw/pci-host/gpex.h
@@ -45,6 +45,7 @@ struct GPEXConfig {
     MemMapEntry pio;
     int         irq;
     PCIBus      *bus;
+    bool        pci_native_hotplug;
 };
 
 typedef struct GPEXIrq GPEXIrq;
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 7e8e0f0298..be5e00a56e 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -129,6 +129,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
         .ecam   = memmap[ecam_id],
         .irq    = irq,
         .bus    = vms->bus,
+        .pci_native_hotplug = !vms->acpi_pcihp,
     };
 
     if (vms->highmem_mmio) {
diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index 1aa2d12026..f1ab30f3d5 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -204,6 +204,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
             if (is_cxl) {
                 build_cxl_osc_method(dev);
             } else {
+                /* pxb bridges do not have ACPI PCI Hot-plug enabled */
                 acpi_dsdt_add_host_bridge_methods(dev, true);
             }
 
@@ -279,7 +280,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
     }
     aml_append(dev, aml_name_decl("_CRS", rbuf));
 
-    acpi_dsdt_add_host_bridge_methods(dev, true);
+    acpi_dsdt_add_host_bridge_methods(dev, cfg->pci_native_hotplug);
 
     Aml *dev_res0 = aml_device("%s", "RES0");
     aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02")));
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 07/22] hw/i386/acpi-build: Turn build_q35_osc_method into a generic method
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (5 preceding siblings ...)
  2025-05-14 17:00 ` [PATCH 06/22] hw/pci-host/gpex-acpi: Propagate hotplug type info from virt machine downto gpex Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-20 12:59   ` Gustavo Romero
  2025-05-14 17:00 ` [PATCH 08/22] hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method Eric Auger
                   ` (15 subsequent siblings)
  22 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

GPEX acpi_dsdt_add_pci_osc() does basically the same as
build_q35_osc_method().

Rename build_q35_osc_method() into build_pci_host_bridge_osc_method()
and move it into hw/acpi/aml-build.c. In a subsequent patch we will
use this later in place of acpi_dsdt_add_pci_osc().

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/acpi/aml-build.h |  2 ++
 hw/acpi/aml-build.c         | 50 ++++++++++++++++++++++++++++++++++
 hw/i386/acpi-build.c        | 54 ++-----------------------------------
 3 files changed, 54 insertions(+), 52 deletions(-)

diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index c18f681342..177d60b414 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -508,4 +508,6 @@ void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
 void build_spcr(GArray *table_data, BIOSLinker *linker,
                 const AcpiSpcrData *f, const uint8_t rev,
                 const char *oem_id, const char *oem_table_id, const char *name);
+
+Aml *build_pci_host_bridge_osc_method(bool enable_native_pcie_hotplug);
 #endif
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index f8f93a9f66..ba1dfe0b52 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -2614,3 +2614,53 @@ Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source)
 
     return var;
 }
+
+Aml *build_pci_host_bridge_osc_method(bool enable_native_pcie_hotplug)
+{
+    Aml *if_ctx;
+    Aml *if_ctx2;
+    Aml *else_ctx;
+    Aml *method;
+    Aml *a_cwd1 = aml_name("CDW1");
+    Aml *a_ctrl = aml_local(0);
+
+    method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
+    aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
+
+    if_ctx = aml_if(aml_equal(
+        aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766")));
+    aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
+    aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
+
+    aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl));
+
+    /*
+     * Always allow native PME, AER (no dependencies)
+     * Allow SHPC (PCI bridges can have SHPC controller)
+     * Disable PCIe Native Hot-plug if ACPI PCI Hot-plug is enabled.
+     */
+    aml_append(if_ctx, aml_and(a_ctrl,
+        aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)), a_ctrl));
+
+    if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
+    /* Unknown revision */
+    aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1));
+    aml_append(if_ctx, if_ctx2);
+
+    if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl)));
+    /* Capabilities bits were masked */
+    aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1));
+    aml_append(if_ctx, if_ctx2);
+
+    /* Update DWORD3 in the buffer */
+    aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3")));
+    aml_append(method, if_ctx);
+
+    else_ctx = aml_else();
+    /* Unrecognized UUID */
+    aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1));
+    aml_append(method, else_ctx);
+
+    aml_append(method, aml_return(aml_arg(3)));
+    return method;
+}
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index b92765fbd9..41fde88b22 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1111,56 +1111,6 @@ static Aml *build_q35_dram_controller(const AcpiMcfgInfo *mcfg)
     return dev;
 }
 
-static Aml *build_q35_osc_method(bool enable_native_pcie_hotplug)
-{
-    Aml *if_ctx;
-    Aml *if_ctx2;
-    Aml *else_ctx;
-    Aml *method;
-    Aml *a_cwd1 = aml_name("CDW1");
-    Aml *a_ctrl = aml_local(0);
-
-    method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
-    aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
-
-    if_ctx = aml_if(aml_equal(
-        aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766")));
-    aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
-    aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
-
-    aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl));
-
-    /*
-     * Always allow native PME, AER (no dependencies)
-     * Allow SHPC (PCI bridges can have SHPC controller)
-     * Disable PCIe Native Hot-plug if ACPI PCI Hot-plug is enabled.
-     */
-    aml_append(if_ctx, aml_and(a_ctrl,
-        aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)), a_ctrl));
-
-    if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
-    /* Unknown revision */
-    aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1));
-    aml_append(if_ctx, if_ctx2);
-
-    if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl)));
-    /* Capabilities bits were masked */
-    aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1));
-    aml_append(if_ctx, if_ctx2);
-
-    /* Update DWORD3 in the buffer */
-    aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3")));
-    aml_append(method, if_ctx);
-
-    else_ctx = aml_else();
-    /* Unrecognized UUID */
-    aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1));
-    aml_append(method, else_ctx);
-
-    aml_append(method, aml_return(aml_arg(3)));
-    return method;
-}
-
 static void build_acpi0017(Aml *table)
 {
     Aml *dev, *scope, *method;
@@ -1231,7 +1181,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
         aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
         aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
         aml_append(dev, aml_name_decl("_UID", aml_int(pcmc->pci_root_uid)));
-        aml_append(dev, build_q35_osc_method(!pm->pcihp_bridge_en));
+        aml_append(dev, build_pci_host_bridge_osc_method(!pm->pcihp_bridge_en));
         aml_append(dev, aml_pci_edsm());
         aml_append(sb_scope, dev);
         if (mcfg_valid) {
@@ -1353,7 +1303,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
                 aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
 
                 /* Expander bridges do not have ACPI PCI Hot-plug enabled */
-                aml_append(dev, build_q35_osc_method(true));
+                aml_append(dev, build_pci_host_bridge_osc_method(true));
             } else {
                 aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
             }
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 08/22] hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (6 preceding siblings ...)
  2025-05-14 17:00 ` [PATCH 07/22] hw/i386/acpi-build: Turn build_q35_osc_method into a generic method Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-20 14:09   ` Gustavo Romero
  2025-05-14 17:00 ` [PATCH 09/22] hw/i386/acpi-build: Introduce build_append_pcihp_resources() helper Eric Auger
                   ` (14 subsequent siblings)
  22 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

gpex build_host_bridge_osc() and x86 originated
build_pci_host_bridge_osc_method() are mostly identical.

In GPEX, SUPP is set to CDW2 but is not further used. CTRL
is same as Local0.

So let gpex code reuse build_pci_host_bridge_osc_method()
and remove build_host_bridge_osc().

Signed-off-by: Eric Auger <eric.auger@redhat.com>

---

The DSDT diff  is given below:
diff --git a/dsdt.dsl_before b/dsdt.dsl_after_osc_change
index 3224a56..fa7558e 100644
--- a/dsdt.dsl_before
+++ b/dsdt.dsl_after_osc_change
@@ -5,13 +5,13 @@
  *
  * Disassembling to symbolic ASL+ operators
  *
- * Disassembly of dsdt.dat, Mon Apr  7 05:33:06 2025
+ * Disassembly of dsdt.dat, Mon Apr  7 05:37:20 2025
  *
  * Original Table Header:
  *     Signature        "DSDT"
- *     Length           0x00001A4F (6735)
+ *     Length           0x00001A35 (6709)
  *     Revision         0x02
- *     Checksum         0xBF
+ *     Checksum         0xDD
  *     OEM ID           "BOCHS "
  *     OEM Table ID     "BXPC    "
  *     OEM Revision     0x00000001 (1)
@@ -1849,27 +1849,26 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPC    ", 0x00000001)
                 {
                     CreateDWordField (Arg3, 0x04, CDW2)
                     CreateDWordField (Arg3, 0x08, CDW3)
-                    SUPP = CDW2 /* \_SB_.PCI0._OSC.CDW2 */
-                    CTRL = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
-                    CTRL &= 0x1F
+                    Local0 = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
+                    Local0 &= 0x1F
                     If ((Arg1 != One))
                     {
                         CDW1 |= 0x08
                     }

-                    If ((CDW3 != CTRL))
+                    If ((CDW3 != Local0))
                     {
                         CDW1 |= 0x10
                     }

-                    CDW3 = CTRL /* \_SB_.PCI0.CTRL */
-                    Return (Arg3)
+                    CDW3 = Local0
                 }
                 Else
                 {
                     CDW1 |= 0x04
-                    Return (Arg3)
                 }
+
+                Return (Arg3)
             }

             Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
---
 hw/pci-host/gpex-acpi.c | 60 +++--------------------------------------
 1 file changed, 4 insertions(+), 56 deletions(-)

diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
index f1ab30f3d5..98c9868c3f 100644
--- a/hw/pci-host/gpex-acpi.c
+++ b/hw/pci-host/gpex-acpi.c
@@ -50,60 +50,7 @@ static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq,
     }
 }
 
-static Aml *build_host_bridge_osc(bool enable_native_pcie_hotplug)
-{
-    Aml *method, *UUID, *ifctx, *ifctx1, *elsectx;
-
-    method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
-    aml_append(method,
-        aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
-
-    /* PCI Firmware Specification 3.0
-     * 4.5.1. _OSC Interface for PCI Host Bridge Devices
-     * The _OSC interface for a PCI/PCI-X/PCI Express hierarchy is
-     * identified by the Universal Unique IDentifier (UUID)
-     * 33DB4D5B-1FF7-401C-9657-7441C03DD766
-     */
-    UUID = aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766");
-    ifctx = aml_if(aml_equal(aml_arg(0), UUID));
-    aml_append(ifctx,
-        aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
-    aml_append(ifctx,
-        aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
-    aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
-    aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
-
-    /*
-     * Allow OS control for SHPCHotplug, PME, AER, PCIeCapability,
-     * and PCIeHotplug depending on enable_native_pcie_hotplug
-     */
-    aml_append(ifctx, aml_and(aml_name("CTRL"),
-               aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)),
-               aml_name("CTRL")));
-
-    ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
-    aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
-                              aml_name("CDW1")));
-    aml_append(ifctx, ifctx1);
-
-    ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL"))));
-    aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10),
-                              aml_name("CDW1")));
-    aml_append(ifctx, ifctx1);
-
-    aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
-    aml_append(ifctx, aml_return(aml_arg(3)));
-    aml_append(method, ifctx);
-
-    elsectx = aml_else();
-    aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4),
-                               aml_name("CDW1")));
-    aml_append(elsectx, aml_return(aml_arg(3)));
-    aml_append(method, elsectx);
-    return method;
-}
-
-static Aml *build_host_bridge_dsm(void)
+static Aml *build_pci_host_bridge_dsm_method(void)
 {
     Aml *method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
     Aml *UUID, *ifctx, *ifctx1, *buf;
@@ -134,8 +81,9 @@ static void acpi_dsdt_add_host_bridge_methods(Aml *dev,
     aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
     aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
     /* Declare an _OSC (OS Control Handoff) method */
-    aml_append(dev, build_host_bridge_osc(enable_native_pcie_hotplug));
-    aml_append(dev, build_host_bridge_dsm());
+    aml_append(dev,
+               build_pci_host_bridge_osc_method(enable_native_pcie_hotplug));
+    aml_append(dev, build_pci_host_bridge_dsm_method());
 }
 
 void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 09/22] hw/i386/acpi-build: Introduce build_append_pcihp_resources() helper
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (7 preceding siblings ...)
  2025-05-14 17:00 ` [PATCH 08/22] hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-20 18:57   ` Gustavo Romero
  2025-05-14 17:00 ` [PATCH 10/22] hw/acpi/pcihp: Add an AmlRegionSpace arg to build_acpi_pci_hotplug Eric Auger
                   ` (13 subsequent siblings)
  22 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Extract the code that reserves resources for ACPI PCI hotplug
into a new helper named build_append_pcihp_resources() and
move it to pcihp.c. We will reuse it on ARM.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/acpi/pcihp.h |  2 ++
 hw/acpi/pcihp.c         | 20 ++++++++++++++++++++
 hw/i386/acpi-build.c    | 15 ++-------------
 3 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 95efe9a804..ec9b010e4a 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -75,6 +75,8 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
 
 void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr);
 void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar);
+void build_append_pcihp_resources(Aml *table,
+                                  uint64_t io_addr, uint64_t io_len);
 
 /* Called on reset */
 void acpi_pcihp_reset(AcpiPciHpState *s);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index e0260f67e6..fb54c31f77 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -685,6 +685,26 @@ void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr)
     aml_append(table, scope);
 }
 
+/* Reserve PCIHP resources */
+void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
+                                  uint64_t io_addr, uint64_t io_len)
+{
+    Aml *dev, *crs;
+
+    dev = aml_device("PHPR");
+    aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
+    aml_append(dev,
+               aml_name_decl("_UID", aml_string("PCI Hotplug resources")));
+    /* device present, functioning, decoding, not shown in UI */
+    aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+    crs = aml_resource_template();
+    aml_append(crs,
+        aml_io(AML_DECODE16, io_addr, io_addr, 1, io_len)
+    );
+    aml_append(dev, aml_name_decl("_CRS", crs));
+    aml_append(scope, dev);
+}
+
 const VMStateDescription vmstate_acpi_pcihp_pci_status = {
     .name = "acpi_pcihp_pci_status",
     .version_id = 1,
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 41fde88b22..ca59185aac 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1432,19 +1432,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 
     /* reserve PCIHP resources */
     if (pm->pcihp_io_len && (pm->pcihp_bridge_en || pm->pcihp_root_en)) {
-        dev = aml_device("PHPR");
-        aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
-        aml_append(dev,
-            aml_name_decl("_UID", aml_string("PCI Hotplug resources")));
-        /* device present, functioning, decoding, not shown in UI */
-        aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
-        crs = aml_resource_template();
-        aml_append(crs,
-            aml_io(AML_DECODE16, pm->pcihp_io_base, pm->pcihp_io_base, 1,
-                   pm->pcihp_io_len)
-        );
-        aml_append(dev, aml_name_decl("_CRS", crs));
-        aml_append(scope, dev);
+        build_append_pcihp_resources(scope,
+                                      pm->pcihp_io_base, pm->pcihp_io_len);
     }
     aml_append(dsdt, scope);
 
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 10/22] hw/acpi/pcihp: Add an AmlRegionSpace arg to build_acpi_pci_hotplug
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (8 preceding siblings ...)
  2025-05-14 17:00 ` [PATCH 09/22] hw/i386/acpi-build: Introduce build_append_pcihp_resources() helper Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-20 18:58   ` Gustavo Romero
  2025-05-14 17:00 ` [PATCH 11/22] hw/i386/acpi-build: Move build_append_notification_callback to pcihp Eric Auger
                   ` (12 subsequent siblings)
  22 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

On ARM we will put the operation regions in AML_SYSTEM_MEMORY.
So let's allow this configuration.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/acpi/pcihp.h | 3 ++-
 hw/acpi/pcihp.c         | 8 ++++----
 hw/i386/acpi-build.c    | 4 ++--
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index ec9b010e4a..525e61a2a9 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -28,6 +28,7 @@
 #define HW_ACPI_PCIHP_H
 
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/aml-build.h"
 #include "hw/hotplug.h"
 
 #define ACPI_PCIHP_IO_BASE_PROP "acpi-pcihp-io-base"
@@ -73,7 +74,7 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
                                          AcpiPciHpState *s, DeviceState *dev,
                                          Error **errp);
 
-void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr);
+void build_acpi_pci_hotplug(Aml *table, AmlRegionSpace rs, uint64_t pcihp_addr);
 void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar);
 void build_append_pcihp_resources(Aml *table,
                                   uint64_t io_addr, uint64_t io_len);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index fb54c31f77..310a5c54bd 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -629,7 +629,7 @@ static Aml *aml_pci_pdsm(void)
     return method;
 }
 
-void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr)
+void build_acpi_pci_hotplug(Aml *table, AmlRegionSpace rs, uint64_t pcihp_addr)
 {
     Aml *scope;
     Aml *field;
@@ -638,21 +638,21 @@ void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr)
     scope =  aml_scope("_SB.PCI0");
 
     aml_append(scope,
-        aml_operation_region("PCST", AML_SYSTEM_IO, aml_int(pcihp_addr), 0x08));
+        aml_operation_region("PCST", rs, aml_int(pcihp_addr), 0x08));
     field = aml_field("PCST", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
     aml_append(field, aml_named_field("PCIU", 32));
     aml_append(field, aml_named_field("PCID", 32));
     aml_append(scope, field);
 
     aml_append(scope,
-        aml_operation_region("SEJ", AML_SYSTEM_IO,
+        aml_operation_region("SEJ", rs,
                              aml_int(pcihp_addr + ACPI_PCIHP_SEJ_BASE), 0x04));
     field = aml_field("SEJ", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
     aml_append(field, aml_named_field("B0EJ", 32));
     aml_append(scope, field);
 
     aml_append(scope,
-        aml_operation_region("BNMR", AML_SYSTEM_IO,
+        aml_operation_region("BNMR", rs,
                              aml_int(pcihp_addr + ACPI_PCIHP_BNMR_BASE), 0x08));
     field = aml_field("BNMR", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
     aml_append(field, aml_named_field("BNUM", 32));
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ca59185aac..87bb3d5cee 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1172,7 +1172,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
         aml_append(dsdt, sb_scope);
 
         if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
-            build_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
+            build_acpi_pci_hotplug(dsdt, AML_SYSTEM_IO, pm->pcihp_io_base);
         }
         build_piix4_pci0_int(dsdt);
     } else if (q35) {
@@ -1216,7 +1216,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
         aml_append(dsdt, sb_scope);
 
         if (pm->pcihp_bridge_en) {
-            build_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
+            build_acpi_pci_hotplug(dsdt, AML_SYSTEM_IO, pm->pcihp_io_base);
         }
         build_q35_pci0_int(dsdt);
     }
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 11/22] hw/i386/acpi-build: Move build_append_notification_callback to pcihp
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (9 preceding siblings ...)
  2025-05-14 17:00 ` [PATCH 10/22] hw/acpi/pcihp: Add an AmlRegionSpace arg to build_acpi_pci_hotplug Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-20 18:58   ` Gustavo Romero
  2025-05-14 17:00 ` [PATCH 12/22] hw/i386/acpi-build: Move build_append_pci_bus_devices/pcihp_slots " Eric Auger
                   ` (11 subsequent siblings)
  22 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

We plan to reuse build_append_notification_callback() on ARM
so let's move it to pcihp.c.

No functional change intended.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/acpi/pcihp.h |  1 +
 hw/acpi/pcihp.c         | 58 +++++++++++++++++++++++++++++++++++++++++
 hw/i386/acpi-build.c    | 58 -----------------------------------------
 3 files changed, 59 insertions(+), 58 deletions(-)

diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 525e61a2a9..7c5d59243f 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -78,6 +78,7 @@ void build_acpi_pci_hotplug(Aml *table, AmlRegionSpace rs, uint64_t pcihp_addr);
 void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar);
 void build_append_pcihp_resources(Aml *table,
                                   uint64_t io_addr, uint64_t io_len);
+bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus);
 
 /* Called on reset */
 void acpi_pcihp_reset(AcpiPciHpState *s);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 310a5c54bd..907a08ac7f 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -39,6 +39,7 @@
 #include "migration/vmstate.h"
 #include "qapi/error.h"
 #include "qom/qom-qobject.h"
+#include "qobject/qnum.h"
 #include "trace.h"
 
 #define ACPI_PCIHP_SIZE 0x0018
@@ -705,6 +706,63 @@ void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
     aml_append(scope, dev);
 }
 
+bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus)
+{
+    Aml *method;
+    PCIBus *sec;
+    QObject *bsel;
+    int nr_notifiers = 0;
+    GQueue *pcnt_bus_list = g_queue_new();
+
+    QLIST_FOREACH(sec, &bus->child, sibling) {
+        Aml *br_scope = aml_scope("S%.02X", sec->parent_dev->devfn);
+        if (pci_bus_is_root(sec)) {
+            continue;
+        }
+        nr_notifiers = nr_notifiers +
+                       build_append_notification_callback(br_scope, sec);
+        /*
+         * add new child scope to parent
+         * and keep track of bus that have PCNT,
+         * bus list is used later to call children PCNTs from this level PCNT
+         */
+        if (nr_notifiers) {
+            g_queue_push_tail(pcnt_bus_list, sec);
+            aml_append(parent_scope, br_scope);
+        }
+    }
+
+    /*
+     * Append PCNT method to notify about events on local and child buses.
+     * ps: hostbridge might not have hotplug (bsel) enabled but might have
+     * child bridges that do have bsel.
+     */
+    method = aml_method("PCNT", 0, AML_NOTSERIALIZED);
+
+    /* If bus supports hotplug select it and notify about local events */
+    bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
+    if (bsel) {
+        uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
+
+        aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
+        aml_append(method, aml_call2("DVNT", aml_name("PCIU"),
+                                     aml_int(1))); /* Device Check */
+        aml_append(method, aml_call2("DVNT", aml_name("PCID"),
+                                     aml_int(3))); /* Eject Request */
+        nr_notifiers++;
+    }
+
+    /* Notify about child bus events in any case */
+    while ((sec = g_queue_pop_head(pcnt_bus_list))) {
+        aml_append(method, aml_name("^S%.02X.PCNT", sec->parent_dev->devfn));
+    }
+
+    aml_append(parent_scope, method);
+    qobject_unref(bsel);
+    g_queue_free(pcnt_bus_list);
+    return !!nr_notifiers;
+}
+
 const VMStateDescription vmstate_acpi_pcihp_pci_status = {
     .name = "acpi_pcihp_pci_status",
     .version_id = 1,
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 87bb3d5cee..f08ce407c8 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -563,64 +563,6 @@ void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
     }
 }
 
-static bool build_append_notification_callback(Aml *parent_scope,
-                                               const PCIBus *bus)
-{
-    Aml *method;
-    PCIBus *sec;
-    QObject *bsel;
-    int nr_notifiers = 0;
-    GQueue *pcnt_bus_list = g_queue_new();
-
-    QLIST_FOREACH(sec, &bus->child, sibling) {
-        Aml *br_scope = aml_scope("S%.02X", sec->parent_dev->devfn);
-        if (pci_bus_is_root(sec)) {
-            continue;
-        }
-        nr_notifiers = nr_notifiers +
-                       build_append_notification_callback(br_scope, sec);
-        /*
-         * add new child scope to parent
-         * and keep track of bus that have PCNT,
-         * bus list is used later to call children PCNTs from this level PCNT
-         */
-        if (nr_notifiers) {
-            g_queue_push_tail(pcnt_bus_list, sec);
-            aml_append(parent_scope, br_scope);
-        }
-    }
-
-    /*
-     * Append PCNT method to notify about events on local and child buses.
-     * ps: hostbridge might not have hotplug (bsel) enabled but might have
-     * child bridges that do have bsel.
-     */
-    method = aml_method("PCNT", 0, AML_NOTSERIALIZED);
-
-    /* If bus supports hotplug select it and notify about local events */
-    bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
-    if (bsel) {
-        uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
-
-        aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
-        aml_append(method, aml_call2("DVNT", aml_name("PCIU"),
-                                     aml_int(1))); /* Device Check */
-        aml_append(method, aml_call2("DVNT", aml_name("PCID"),
-                                     aml_int(3))); /* Eject Request */
-        nr_notifiers++;
-    }
-
-    /* Notify about child bus events in any case */
-    while ((sec = g_queue_pop_head(pcnt_bus_list))) {
-        aml_append(method, aml_name("^S%.02X.PCNT", sec->parent_dev->devfn));
-    }
-
-    aml_append(parent_scope, method);
-    qobject_unref(bsel);
-    g_queue_free(pcnt_bus_list);
-    return !!nr_notifiers;
-}
-
 /*
  * build_prt - Define interrupt routing rules
  *
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 12/22] hw/i386/acpi-build: Move build_append_pci_bus_devices/pcihp_slots to pcihp
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (10 preceding siblings ...)
  2025-05-14 17:00 ` [PATCH 11/22] hw/i386/acpi-build: Move build_append_notification_callback to pcihp Eric Auger
@ 2025-05-14 17:00 ` Eric Auger
  2025-05-20 19:59   ` Gustavo Romero
  2025-05-14 17:01 ` [PATCH 13/22] hw/i386/acpi-build: Introduce and use acpi_get_pci_host Eric Auger
                   ` (10 subsequent siblings)
  22 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:00 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

We intend to reuse build_append_pci_bus_devices and
build_append_pcihp_slots on ARM. So Let's move them to
hw/acpi/pcihp.c as well as all static helpers they
use.

No functional change intended.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/acpi/pci.h   |   1 -
 include/hw/acpi/pcihp.h |   2 +
 hw/acpi/pcihp.c         | 173 ++++++++++++++++++++++++++++++++++++++++
 hw/i386/acpi-build.c    | 172 ---------------------------------------
 4 files changed, 175 insertions(+), 173 deletions(-)

diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h
index ab0187a894..4dca22c0e2 100644
--- a/include/hw/acpi/pci.h
+++ b/include/hw/acpi/pci.h
@@ -37,7 +37,6 @@ typedef struct AcpiMcfgInfo {
 void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info,
                 const char *oem_id, const char *oem_table_id);
 
-void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
 void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope);
 
 void build_srat_generic_affinity_structures(GArray *table_data);
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 7c5d59243f..4d820b4baf 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -80,6 +80,8 @@ void build_append_pcihp_resources(Aml *table,
                                   uint64_t io_addr, uint64_t io_len);
 bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus);
 
+void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
+
 /* Called on reset */
 void acpi_pcihp_reset(AcpiPciHpState *s);
 
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 907a08ac7f..942669ea89 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -27,6 +27,7 @@
 #include "qemu/osdep.h"
 #include "hw/acpi/pcihp.h"
 #include "hw/acpi/aml-build.h"
+#include "hw/acpi/acpi_aml_interface.h"
 #include "hw/pci-host/i440fx.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bridge.h"
@@ -763,6 +764,178 @@ bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus)
     return !!nr_notifiers;
 }
 
+static void build_append_pcihp_notify_entry(Aml *method, int slot)
+{
+    Aml *if_ctx;
+    int32_t devfn = PCI_DEVFN(slot, 0);
+
+    if_ctx = aml_if(aml_and(aml_arg(0), aml_int(0x1U << slot), NULL));
+    aml_append(if_ctx, aml_notify(aml_name("S%.02X", devfn), aml_arg(1)));
+    aml_append(method, if_ctx);
+}
+
+static bool is_devfn_ignored_generic(const int devfn, const PCIBus *bus)
+{
+    const PCIDevice *pdev = bus->devices[devfn];
+
+    if (PCI_FUNC(devfn)) {
+        if (IS_PCI_BRIDGE(pdev)) {
+            /*
+             * Ignore only hotplugged PCI bridges on !0 functions, but
+             * allow describing cold plugged bridges on all functions
+             */
+            if (DEVICE(pdev)->hotplugged) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+static bool is_devfn_ignored_hotplug(const int devfn, const PCIBus *bus)
+{
+    PCIDevice *pdev = bus->devices[devfn];
+    if (pdev) {
+        return is_devfn_ignored_generic(devfn, bus) ||
+               !DEVICE_GET_CLASS(pdev)->hotpluggable ||
+               /* Cold plugged bridges aren't themselves hot-pluggable */
+               (IS_PCI_BRIDGE(pdev) && !DEVICE(pdev)->hotplugged);
+    } else { /* non populated slots */
+         /*
+          * hotplug is supported only for non-multifunction device
+          * so generate device description only for function 0
+          */
+        if (PCI_FUNC(devfn) ||
+            (pci_bus_is_express(bus) && PCI_SLOT(devfn) > 0)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static Aml *aml_pci_static_endpoint_dsm(PCIDevice *pdev)
+{
+    Aml *method;
+
+    g_assert(pdev->acpi_index != 0);
+    method = aml_method("_DSM", 4, AML_SERIALIZED);
+    {
+        Aml *params = aml_local(0);
+        Aml *pkg = aml_package(1);
+        aml_append(pkg, aml_int(pdev->acpi_index));
+        aml_append(method, aml_store(pkg, params));
+        aml_append(method,
+            aml_return(aml_call5("EDSM", aml_arg(0), aml_arg(1),
+                                 aml_arg(2), aml_arg(3), params))
+        );
+    }
+    return method;
+}
+
+static Aml *aml_pci_device_dsm(void)
+{
+    Aml *method;
+
+    method = aml_method("_DSM", 4, AML_SERIALIZED);
+    {
+        Aml *params = aml_local(0);
+        Aml *pkg = aml_package(2);
+        aml_append(pkg, aml_int(0));
+        aml_append(pkg, aml_int(0));
+        aml_append(method, aml_store(pkg, params));
+        aml_append(method,
+            aml_store(aml_name("BSEL"), aml_index(params, aml_int(0))));
+        aml_append(method,
+            aml_store(aml_name("ASUN"), aml_index(params, aml_int(1))));
+        aml_append(method,
+            aml_return(aml_call5("PDSM", aml_arg(0), aml_arg(1),
+                                 aml_arg(2), aml_arg(3), params))
+        );
+    }
+    return method;
+}
+
+void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus)
+{
+    int devfn;
+    Aml *dev, *notify_method = NULL, *method;
+    QObject *bsel = object_property_get_qobject(OBJECT(bus),
+                        ACPI_PCIHP_PROP_BSEL, NULL);
+    uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
+    qobject_unref(bsel);
+
+    aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
+    notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED);
+
+    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
+        int slot = PCI_SLOT(devfn);
+        int adr = slot << 16 | PCI_FUNC(devfn);
+
+        if (is_devfn_ignored_hotplug(devfn, bus)) {
+            continue;
+        }
+
+        if (bus->devices[devfn]) {
+            dev = aml_scope("S%.02X", devfn);
+        } else {
+            dev = aml_device("S%.02X", devfn);
+            aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
+        }
+
+        /*
+         * Can't declare _SUN here for every device as it changes 'slot'
+         * enumeration order in linux kernel, so use another variable for it
+         */
+        aml_append(dev, aml_name_decl("ASUN", aml_int(slot)));
+        aml_append(dev, aml_pci_device_dsm());
+
+        aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
+        /* add _EJ0 to make slot hotpluggable  */
+        method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
+        aml_append(method,
+            aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
+        );
+        aml_append(dev, method);
+
+        build_append_pcihp_notify_entry(notify_method, slot);
+
+        /* device descriptor has been composed, add it into parent context */
+        aml_append(parent_scope, dev);
+    }
+    aml_append(parent_scope, notify_method);
+}
+
+void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
+{
+    int devfn;
+    Aml *dev;
+
+    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
+        /* ACPI spec: 1.0b: Table 6-2 _ADR Object Bus Types, PCI type */
+        int adr = PCI_SLOT(devfn) << 16 | PCI_FUNC(devfn);
+        PCIDevice *pdev = bus->devices[devfn];
+
+        if (!pdev || is_devfn_ignored_generic(devfn, bus)) {
+            continue;
+        }
+
+        /* start to compose PCI device descriptor */
+        dev = aml_device("S%.02X", devfn);
+        aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
+
+        call_dev_aml_func(DEVICE(bus->devices[devfn]), dev);
+        /* add _DSM if device has acpi-index set */
+        if (pdev->acpi_index &&
+            !object_property_get_bool(OBJECT(pdev), "hotpluggable",
+                                      &error_abort)) {
+            aml_append(dev, aml_pci_static_endpoint_dsm(pdev));
+        }
+
+        /* device descriptor has been composed, add it into parent context */
+        aml_append(parent_scope, dev);
+    }
+}
+
 const VMStateDescription vmstate_acpi_pcihp_pci_status = {
     .name = "acpi_pcihp_pci_status",
     .version_id = 1,
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index f08ce407c8..06b4b8eed4 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -338,29 +338,6 @@ build_facs(GArray *table_data)
     g_array_append_vals(table_data, reserved, 40); /* Reserved */
 }
 
-static Aml *aml_pci_device_dsm(void)
-{
-    Aml *method;
-
-    method = aml_method("_DSM", 4, AML_SERIALIZED);
-    {
-        Aml *params = aml_local(0);
-        Aml *pkg = aml_package(2);
-        aml_append(pkg, aml_int(0));
-        aml_append(pkg, aml_int(0));
-        aml_append(method, aml_store(pkg, params));
-        aml_append(method,
-            aml_store(aml_name("BSEL"), aml_index(params, aml_int(0))));
-        aml_append(method,
-            aml_store(aml_name("ASUN"), aml_index(params, aml_int(1))));
-        aml_append(method,
-            aml_return(aml_call5("PDSM", aml_arg(0), aml_arg(1),
-                                 aml_arg(2), aml_arg(3), params))
-        );
-    }
-    return method;
-}
-
 static Aml *aml_pci_edsm(void)
 {
     Aml *method, *ifctx;
@@ -414,155 +391,6 @@ static Aml *aml_pci_edsm(void)
     return method;
 }
 
-static Aml *aml_pci_static_endpoint_dsm(PCIDevice *pdev)
-{
-    Aml *method;
-
-    g_assert(pdev->acpi_index != 0);
-    method = aml_method("_DSM", 4, AML_SERIALIZED);
-    {
-        Aml *params = aml_local(0);
-        Aml *pkg = aml_package(1);
-        aml_append(pkg, aml_int(pdev->acpi_index));
-        aml_append(method, aml_store(pkg, params));
-        aml_append(method,
-            aml_return(aml_call5("EDSM", aml_arg(0), aml_arg(1),
-                                 aml_arg(2), aml_arg(3), params))
-        );
-    }
-    return method;
-}
-
-static void build_append_pcihp_notify_entry(Aml *method, int slot)
-{
-    Aml *if_ctx;
-    int32_t devfn = PCI_DEVFN(slot, 0);
-
-    if_ctx = aml_if(aml_and(aml_arg(0), aml_int(0x1U << slot), NULL));
-    aml_append(if_ctx, aml_notify(aml_name("S%.02X", devfn), aml_arg(1)));
-    aml_append(method, if_ctx);
-}
-
-static bool is_devfn_ignored_generic(const int devfn, const PCIBus *bus)
-{
-    const PCIDevice *pdev = bus->devices[devfn];
-
-    if (PCI_FUNC(devfn)) {
-        if (IS_PCI_BRIDGE(pdev)) {
-            /*
-             * Ignore only hotplugged PCI bridges on !0 functions, but
-             * allow describing cold plugged bridges on all functions
-             */
-            if (DEVICE(pdev)->hotplugged) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-static bool is_devfn_ignored_hotplug(const int devfn, const PCIBus *bus)
-{
-    PCIDevice *pdev = bus->devices[devfn];
-    if (pdev) {
-        return is_devfn_ignored_generic(devfn, bus) ||
-               !DEVICE_GET_CLASS(pdev)->hotpluggable ||
-               /* Cold plugged bridges aren't themselves hot-pluggable */
-               (IS_PCI_BRIDGE(pdev) && !DEVICE(pdev)->hotplugged);
-    } else { /* non populated slots */
-         /*
-         * hotplug is supported only for non-multifunction device
-         * so generate device description only for function 0
-         */
-        if (PCI_FUNC(devfn) ||
-            (pci_bus_is_express(bus) && PCI_SLOT(devfn) > 0)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus)
-{
-    int devfn;
-    Aml *dev, *notify_method = NULL, *method;
-    QObject *bsel = object_property_get_qobject(OBJECT(bus),
-                        ACPI_PCIHP_PROP_BSEL, NULL);
-    uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
-    qobject_unref(bsel);
-
-    aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
-    notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED);
-
-    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
-        int slot = PCI_SLOT(devfn);
-        int adr = slot << 16 | PCI_FUNC(devfn);
-
-        if (is_devfn_ignored_hotplug(devfn, bus)) {
-            continue;
-        }
-
-        if (bus->devices[devfn]) {
-            dev = aml_scope("S%.02X", devfn);
-        } else {
-            dev = aml_device("S%.02X", devfn);
-            aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
-        }
-
-        /*
-         * Can't declare _SUN here for every device as it changes 'slot'
-         * enumeration order in linux kernel, so use another variable for it
-         */
-        aml_append(dev, aml_name_decl("ASUN", aml_int(slot)));
-        aml_append(dev, aml_pci_device_dsm());
-
-        aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
-        /* add _EJ0 to make slot hotpluggable  */
-        method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
-        aml_append(method,
-            aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
-        );
-        aml_append(dev, method);
-
-        build_append_pcihp_notify_entry(notify_method, slot);
-
-        /* device descriptor has been composed, add it into parent context */
-        aml_append(parent_scope, dev);
-    }
-    aml_append(parent_scope, notify_method);
-}
-
-void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
-{
-    int devfn;
-    Aml *dev;
-
-    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
-        /* ACPI spec: 1.0b: Table 6-2 _ADR Object Bus Types, PCI type */
-        int adr = PCI_SLOT(devfn) << 16 | PCI_FUNC(devfn);
-        PCIDevice *pdev = bus->devices[devfn];
-
-        if (!pdev || is_devfn_ignored_generic(devfn, bus)) {
-            continue;
-        }
-
-        /* start to compose PCI device descriptor */
-        dev = aml_device("S%.02X", devfn);
-        aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
-
-        call_dev_aml_func(DEVICE(bus->devices[devfn]), dev);
-        /* add _DSM if device has acpi-index set */
-        if (pdev->acpi_index &&
-            !object_property_get_bool(OBJECT(pdev), "hotpluggable",
-                                      &error_abort)) {
-            aml_append(dev, aml_pci_static_endpoint_dsm(pdev));
-        }
-
-        /* device descriptor has been composed, add it into parent context */
-        aml_append(parent_scope, dev);
-    }
-}
-
 /*
  * build_prt - Define interrupt routing rules
  *
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 13/22] hw/i386/acpi-build: Introduce and use acpi_get_pci_host
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (11 preceding siblings ...)
  2025-05-14 17:00 ` [PATCH 12/22] hw/i386/acpi-build: Move build_append_pci_bus_devices/pcihp_slots " Eric Auger
@ 2025-05-14 17:01 ` Eric Auger
  2025-05-20 20:00   ` Gustavo Romero
  2025-05-14 17:01 ` [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place Eric Auger
                   ` (9 subsequent siblings)
  22 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:01 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

pcihp acpi_set_pci_info() generic code currently uses
acpi_get_i386_pci_host() to retrieve the pci host bridge.

Let's rename acpi_get_i386_pci_host into acpi_get_pci_host and
move it in pci generic code.

The helper is augmented with the support of ARM GPEX.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/acpi/pci.h |  2 ++
 hw/acpi/pci.c         | 20 ++++++++++++++++++++
 hw/acpi/pcihp.c       |  3 ++-
 hw/i386/acpi-build.c  | 24 ++++--------------------
 4 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h
index 4dca22c0e2..310cbd02db 100644
--- a/include/hw/acpi/pci.h
+++ b/include/hw/acpi/pci.h
@@ -41,4 +41,6 @@ void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope);
 
 void build_srat_generic_affinity_structures(GArray *table_data);
 
+Object *acpi_get_pci_host(void);
+
 #endif
diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c
index d511a85029..4191886ebe 100644
--- a/hw/acpi/pci.c
+++ b/hw/acpi/pci.c
@@ -26,6 +26,7 @@
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
 #include "qom/object_interfaces.h"
+#include "qom/object.h"
 #include "qapi/error.h"
 #include "hw/boards.h"
 #include "hw/acpi/aml-build.h"
@@ -33,6 +34,9 @@
 #include "hw/pci/pci_bridge.h"
 #include "hw/pci/pci_device.h"
 #include "hw/pci/pcie_host.h"
+#include "hw/pci-host/i440fx.h"
+#include "hw/pci-host/q35.h"
+#include "hw/pci-host/gpex.h"
 
 /*
  * PCI Firmware Specification, Revision 3.0
@@ -301,3 +305,19 @@ void build_srat_generic_affinity_structures(GArray *table_data)
     object_child_foreach_recursive(object_get_root(), build_acpi_generic_port,
                                    table_data);
 }
+
+Object *acpi_get_pci_host(void)
+{
+    Object *host;
+
+    host = object_resolve_type_unambiguous(TYPE_I440FX_PCI_HOST_BRIDGE, NULL);
+    if (host) {
+        return host;
+    }
+    host = object_resolve_type_unambiguous(TYPE_Q35_HOST_DEVICE, NULL);
+    if (host) {
+        return host;
+    }
+    host = object_resolve_type_unambiguous(TYPE_GPEX_HOST, NULL);
+    return host;
+}
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 942669ea89..d800371ddc 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -36,6 +36,7 @@
 #include "hw/pci-bridge/xio3130_downstream.h"
 #include "hw/i386/acpi-build.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/pci.h"
 #include "hw/pci/pci_bus.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
@@ -102,7 +103,7 @@ static void *acpi_set_bsel(PCIBus *bus, void *opaque)
 static void acpi_set_pci_info(bool has_bridge_hotplug)
 {
     static bool bsel_is_set;
-    Object *host = acpi_get_i386_pci_host();
+    Object *host = acpi_get_pci_host();
     PCIBus *bus;
     BSELInfo info = { .bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT,
                       .has_bridge_hotplug = has_bridge_hotplug };
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 06b4b8eed4..bcfba2ccb3 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -269,27 +269,11 @@ static void acpi_get_misc_info(AcpiMiscInfo *info)
 #endif
 }
 
-/*
- * Because of the PXB hosts we cannot simply query TYPE_PCI_HOST_BRIDGE.
- * On i386 arch we only have two pci hosts, so we can look only for them.
- */
-Object *acpi_get_i386_pci_host(void)
-{
-    PCIHostState *host;
-
-    host = PCI_HOST_BRIDGE(object_resolve_path("/machine/i440fx", NULL));
-    if (!host) {
-        host = PCI_HOST_BRIDGE(object_resolve_path("/machine/q35", NULL));
-    }
-
-    return OBJECT(host);
-}
-
 static void acpi_get_pci_holes(Range *hole, Range *hole64)
 {
     Object *pci_host;
 
-    pci_host = acpi_get_i386_pci_host();
+    pci_host = acpi_get_pci_host();
 
     if (!pci_host) {
         return;
@@ -1245,7 +1229,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 
     sb_scope = aml_scope("\\_SB");
     {
-        Object *pci_host = acpi_get_i386_pci_host();
+        Object *pci_host = acpi_get_pci_host();
 
         if (pci_host) {
             PCIBus *pbus = PCI_HOST_BRIDGE(pci_host)->bus;
@@ -1306,7 +1290,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
     if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
         bool has_pcnt;
 
-        Object *pci_host = acpi_get_i386_pci_host();
+        Object *pci_host = acpi_get_pci_host();
         PCIBus *b = PCI_HOST_BRIDGE(pci_host)->bus;
 
         scope = aml_scope("\\_SB.PCI0");
@@ -1946,7 +1930,7 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
     Object *pci_host;
     QObject *o;
 
-    pci_host = acpi_get_i386_pci_host();
+    pci_host = acpi_get_pci_host();
     if (!pci_host) {
         return false;
     }
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (12 preceding siblings ...)
  2025-05-14 17:01 ` [PATCH 13/22] hw/i386/acpi-build: Introduce and use acpi_get_pci_host Eric Auger
@ 2025-05-14 17:01 ` Eric Auger
  2025-05-21 15:26   ` Gustavo Romero
  2025-05-14 17:01 ` [PATCH 15/22] hw/arm/virt-acpi-build: Modify the DSDT ACPI table to enable ACPI PCI hotplug Eric Auger
                   ` (8 subsequent siblings)
  22 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:01 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Move aml_pci_edsm to pcihp since we want to reuse that for
ARM and acpi-index support.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/acpi/pcihp.h |  2 ++
 hw/acpi/pcihp.c         | 53 +++++++++++++++++++++++++++++++++++++++++
 hw/i386/acpi-build.c    | 53 -----------------------------------------
 3 files changed, 55 insertions(+), 53 deletions(-)

diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 4d820b4baf..bc31dbff39 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -82,6 +82,8 @@ bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus);
 
 void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
 
+Aml *aml_pci_edsm(void);
+
 /* Called on reset */
 void acpi_pcihp_reset(AcpiPciHpState *s);
 
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index d800371ddc..57fe8938b1 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -937,6 +937,59 @@ void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
     }
 }
 
+Aml *aml_pci_edsm(void)
+{
+    Aml *method, *ifctx;
+    Aml *zero = aml_int(0);
+    Aml *func = aml_arg(2);
+    Aml *ret = aml_local(0);
+    Aml *aidx = aml_local(1);
+    Aml *params = aml_arg(4);
+
+    method = aml_method("EDSM", 5, AML_SERIALIZED);
+
+    /* get supported functions */
+    ifctx = aml_if(aml_equal(func, zero));
+    {
+        /* 1: have supported functions */
+        /* 7: support for function 7 */
+        const uint8_t caps = 1 | BIT(7);
+        build_append_pci_dsm_func0_common(ifctx, ret);
+        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret, zero)));
+        aml_append(ifctx, aml_return(ret));
+    }
+    aml_append(method, ifctx);
+
+    /* handle specific functions requests */
+    /*
+     * PCI Firmware Specification 3.1
+     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
+     *        Operating Systems
+     */
+    ifctx = aml_if(aml_equal(func, aml_int(7)));
+    {
+       Aml *pkg = aml_package(2);
+       aml_append(pkg, zero);
+       /* optional, if not impl. should return null string */
+       aml_append(pkg, aml_string("%s", ""));
+       aml_append(ifctx, aml_store(pkg, ret));
+
+       /*
+        * IASL is fine when initializing Package with computational data,
+        * however it makes guest unhappy /it fails to process such AML/.
+        * So use runtime assignment to set acpi-index after initializer
+        * to make OSPM happy.
+        */
+       aml_append(ifctx,
+           aml_store(aml_derefof(aml_index(params, aml_int(0))), aidx));
+       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
+       aml_append(ifctx, aml_return(ret));
+    }
+    aml_append(method, ifctx);
+
+    return method;
+}
+
 const VMStateDescription vmstate_acpi_pcihp_pci_status = {
     .name = "acpi_pcihp_pci_status",
     .version_id = 1,
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index bcfba2ccb3..385e75d061 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -322,59 +322,6 @@ build_facs(GArray *table_data)
     g_array_append_vals(table_data, reserved, 40); /* Reserved */
 }
 
-static Aml *aml_pci_edsm(void)
-{
-    Aml *method, *ifctx;
-    Aml *zero = aml_int(0);
-    Aml *func = aml_arg(2);
-    Aml *ret = aml_local(0);
-    Aml *aidx = aml_local(1);
-    Aml *params = aml_arg(4);
-
-    method = aml_method("EDSM", 5, AML_SERIALIZED);
-
-    /* get supported functions */
-    ifctx = aml_if(aml_equal(func, zero));
-    {
-        /* 1: have supported functions */
-        /* 7: support for function 7 */
-        const uint8_t caps = 1 | BIT(7);
-        build_append_pci_dsm_func0_common(ifctx, ret);
-        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret, zero)));
-        aml_append(ifctx, aml_return(ret));
-    }
-    aml_append(method, ifctx);
-
-    /* handle specific functions requests */
-    /*
-     * PCI Firmware Specification 3.1
-     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
-     *        Operating Systems
-     */
-    ifctx = aml_if(aml_equal(func, aml_int(7)));
-    {
-       Aml *pkg = aml_package(2);
-       aml_append(pkg, zero);
-       /* optional, if not impl. should return null string */
-       aml_append(pkg, aml_string("%s", ""));
-       aml_append(ifctx, aml_store(pkg, ret));
-
-       /*
-        * IASL is fine when initializing Package with computational data,
-        * however it makes guest unhappy /it fails to process such AML/.
-        * So use runtime assignment to set acpi-index after initializer
-        * to make OSPM happy.
-        */
-       aml_append(ifctx,
-           aml_store(aml_derefof(aml_index(params, aml_int(0))), aidx));
-       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
-       aml_append(ifctx, aml_return(ret));
-    }
-    aml_append(method, ifctx);
-
-    return method;
-}
-
 /*
  * build_prt - Define interrupt routing rules
  *
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 15/22] hw/arm/virt-acpi-build: Modify the DSDT ACPI table to enable ACPI PCI hotplug
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (13 preceding siblings ...)
  2025-05-14 17:01 ` [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place Eric Auger
@ 2025-05-14 17:01 ` Eric Auger
  2025-05-14 17:01 ` [PATCH 16/22] hw/acpi/ged: Prepare the device to react to PCI hotplug events Eric Auger
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:01 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Modify the DSDT ACPI table to enable ACPI PCI hotplug.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/arm/virt.h    |  1 +
 hw/arm/virt-acpi-build.c | 25 +++++++++++++++++++++++++
 hw/arm/virt.c            |  1 +
 hw/arm/Kconfig           |  2 ++
 4 files changed, 29 insertions(+)

diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 10ea581f06..1b2e2e1284 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -79,6 +79,7 @@ enum {
     VIRT_ACPI_GED,
     VIRT_NVDIMM_ACPI,
     VIRT_PVTIME,
+    VIRT_ACPI_PCIHP,
     VIRT_LOWMEMMAP_LAST,
 };
 
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index be5e00a56e..2b642e2426 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -34,6 +34,7 @@
 #include "hw/core/cpu.h"
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/pcihp.h"
 #include "hw/nvram/fw_cfg_acpi.h"
 #include "hw/acpi/bios-linker-loader.h"
 #include "hw/acpi/aml-build.h"
@@ -836,6 +837,30 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
                          (irqmap[VIRT_MMIO] + ARM_SPI_BASE),
                          0, NUM_VIRTIO_TRANSPORTS);
     acpi_dsdt_add_pci(scope, memmap, irqmap[VIRT_PCIE] + ARM_SPI_BASE, vms);
+
+    aml_append(dsdt, scope);
+
+    if (vms->acpi_pcihp) {
+        Aml *pci0_scope = aml_scope("\\_SB.PCI0");
+
+        aml_append(pci0_scope, aml_pci_edsm());
+        build_acpi_pci_hotplug(dsdt, AML_SYSTEM_MEMORY,
+                               memmap[VIRT_ACPI_PCIHP].base);
+        build_append_pcihp_resources(pci0_scope,
+                                     memmap[VIRT_ACPI_PCIHP].base,
+                                     memmap[VIRT_ACPI_PCIHP].size);
+
+        /* Scan all PCI buses. Generate tables to support hotplug. */
+        build_append_pci_bus_devices(pci0_scope, vms->bus);
+        if (object_property_find(OBJECT(vms->bus), ACPI_PCIHP_PROP_BSEL)) {
+            build_append_pcihp_slots(pci0_scope, vms->bus);
+        }
+        build_append_notification_callback(pci0_scope, vms->bus);
+        aml_append(dsdt, pci0_scope);
+    }
+
+    scope = aml_scope("\\_SB");
+
     if (vms->acpi_dev) {
         build_ged_aml(scope, "\\_SB."GED_DEVICE,
                       HOTPLUG_HANDLER(vms->acpi_dev),
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a0deeaf2b3..4aa40c8e8b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -183,6 +183,7 @@ static const MemMapEntry base_memmap[] = {
     [VIRT_NVDIMM_ACPI] =        { 0x09090000, NVDIMM_ACPI_IO_LEN},
     [VIRT_PVTIME] =             { 0x090a0000, 0x00010000 },
     [VIRT_SECURE_GPIO] =        { 0x090b0000, 0x00001000 },
+    [VIRT_ACPI_PCIHP] =         { 0x090c0000, 0x00001000 },
     [VIRT_MMIO] =               { 0x0a000000, 0x00000200 },
     /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
     [VIRT_PLATFORM_BUS] =       { 0x0c000000, 0x02000000 },
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index a55b44d7bd..572b4dabd5 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -34,6 +34,8 @@ config ARM_VIRT
     select ACPI_HW_REDUCED
     select ACPI_APEI
     select ACPI_VIOT
+    select ACPI_PCIHP
+    select ACPI_PCI_BRIDGE
     select VIRTIO_MEM_SUPPORTED
     select ACPI_CXL
     select ACPI_HMAT
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 16/22] hw/acpi/ged: Prepare the device to react to PCI hotplug events
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (14 preceding siblings ...)
  2025-05-14 17:01 ` [PATCH 15/22] hw/arm/virt-acpi-build: Modify the DSDT ACPI table to enable ACPI PCI hotplug Eric Auger
@ 2025-05-14 17:01 ` Eric Auger
  2025-05-25 15:34   ` Philippe Mathieu-Daudé
  2025-05-14 17:01 ` [PATCH 17/22] hw/acpi/ged: Call pcihp plug callbacks in hotplug handler implementation Eric Auger
                   ` (6 subsequent siblings)
  22 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:01 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

QEMU will notify the OS about PCI hotplug/hotunplug events through
GED interrupts. Let the GED device handle a new PCI hotplug event.
On its occurrence it calls the \\_SB.PCI0.PCNT method with the BLCK
mutex held.

The GED device uses a dedicated MMIO region that will be mapped
by the machine code.

At this point the GED still does not support PCI device hotplug in
its TYPE_HOTPLUG_HANDLER implementation. This will come in a
subsequent patch.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/acpi/generic_event_device.h |  5 +++++
 include/hw/acpi/pcihp.h                |  2 ++
 hw/acpi/generic_event_device.c         | 15 +++++++++++++++
 hw/acpi/pcihp.c                        |  1 -
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
index d2dac87b4a..28be6c0582 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -63,6 +63,7 @@
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/ghes.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/pcihp.h"
 #include "qom/object.h"
 
 #define ACPI_POWER_BUTTON_DEVICE "PWRB"
@@ -101,6 +102,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
 #define ACPI_GED_PWR_DOWN_EVT      0x2
 #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4
 #define ACPI_GED_CPU_HOTPLUG_EVT    0x8
+#define ACPI_GED_PCI_HOTPLUG_EVT    0x10
 
 typedef struct GEDState {
     MemoryRegion evt;
@@ -114,6 +116,9 @@ struct AcpiGedState {
     MemoryRegion container_memhp;
     CPUHotplugState cpuhp_state;
     MemoryRegion container_cpuhp;
+    AcpiPciHpState pcihp_state;
+    MemoryRegion container_pcihp;
+
     GEDState ged_state;
     uint32_t ged_event_bitmap;
     qemu_irq irq;
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index bc31dbff39..bda5ea24b5 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -38,6 +38,8 @@
 #define ACPI_PCIHP_SEJ_BASE 0x8
 #define ACPI_PCIHP_BNMR_BASE 0x10
 
+#define ACPI_PCIHP_SIZE 0x0018
+
 typedef struct AcpiPciHpPciStatus {
     uint32_t up;
     uint32_t down;
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 7a62f8d5bc..dc3620553d 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/pcihp.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
@@ -26,6 +27,7 @@ static const uint32_t ged_supported_events[] = {
     ACPI_GED_PWR_DOWN_EVT,
     ACPI_GED_NVDIMM_HOTPLUG_EVT,
     ACPI_GED_CPU_HOTPLUG_EVT,
+    ACPI_GED_PCI_HOTPLUG_EVT,
 };
 
 /*
@@ -121,6 +123,12 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
                            aml_notify(aml_name("\\_SB.NVDR"),
                                       aml_int(0x80)));
                 break;
+            case ACPI_GED_PCI_HOTPLUG_EVT:
+                aml_append(if_ctx,
+                           aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF));
+                aml_append(if_ctx, aml_call0("\\_SB.PCI0.PCNT"));
+                aml_append(if_ctx, aml_release(aml_name("\\_SB.PCI0.BLCK")));
+                break;
             default:
                 /*
                  * Please make sure all the events in ged_supported_events[]
@@ -299,6 +307,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
         sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
     } else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
         sel = ACPI_GED_CPU_HOTPLUG_EVT;
+    } else if (ev & ACPI_PCI_HOTPLUG_STATUS) {
+        sel = ACPI_GED_PCI_HOTPLUG_EVT;
     } else {
         /* Unknown event. Return without generating interrupt. */
         warn_report("GED: Unsupported event %d. No irq injected", ev);
@@ -428,6 +438,11 @@ static void acpi_ged_realize(DeviceState *dev, Error **errp)
             cpu_hotplug_hw_init(&s->container_cpuhp, OBJECT(dev),
                                 &s->cpuhp_state, 0);
             break;
+        case ACPI_GED_PCI_HOTPLUG_EVT:
+            memory_region_init(&s->container_pcihp, OBJECT(dev),
+                                "pcihp container",
+                                ACPI_PCIHP_SIZE);
+            sysbus_init_mmio(sbd, &s->container_pcihp);
         }
         ged_events--;
     }
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 57fe8938b1..e87846a1fa 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -44,7 +44,6 @@
 #include "qobject/qnum.h"
 #include "trace.h"
 
-#define ACPI_PCIHP_SIZE 0x0018
 #define PCI_UP_BASE 0x0000
 #define PCI_DOWN_BASE 0x0004
 #define PCI_EJ_BASE 0x0008
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 17/22] hw/acpi/ged: Call pcihp plug callbacks in hotplug handler implementation
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (15 preceding siblings ...)
  2025-05-14 17:01 ` [PATCH 16/22] hw/acpi/ged: Prepare the device to react to PCI hotplug events Eric Auger
@ 2025-05-14 17:01 ` Eric Auger
  2025-05-14 17:01 ` [PATCH 18/22] hw/acpi/ged: Support migration of AcpiPciHpState Eric Auger
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:01 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Add PCI device related code in the TYPE_HOTPLUG_HANDLER
implementation.

For a PCI device hotplug/hotunplug event, the code routes to
acpi_pcihp_device callbacks (pre_plug_cb, plug_cb, unplug_request_cb,
unplug_cb).

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 hw/acpi/generic_event_device.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index dc3620553d..519329e2ef 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -17,6 +17,7 @@
 #include "hw/irq.h"
 #include "hw/mem/pc-dimm.h"
 #include "hw/mem/nvdimm.h"
+#include "hw/pci/pci_device.h"
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
 #include "qemu/error-report.h"
@@ -235,6 +236,17 @@ static const MemoryRegionOps ged_regs_ops = {
     },
 };
 
+static void acpi_ged_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+                                        DeviceState *dev, Error **errp)
+{
+    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        acpi_pcihp_device_pre_plug_cb(hotplug_dev, dev, errp);
+    } else {
+        error_setg(errp, "virt: device pre plug request for unsupported device"
+                   " type: %s", object_get_typename(OBJECT(dev)));
+    }
+}
+
 static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
                                     DeviceState *dev, Error **errp)
 {
@@ -248,6 +260,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
         }
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
         acpi_cpu_plug_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        acpi_pcihp_device_plug_cb(hotplug_dev, &s->pcihp_state, dev, errp);
     } else {
         error_setg(errp, "virt: device plug request for unsupported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -264,6 +278,9 @@ static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev,
         acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
         acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        acpi_pcihp_device_unplug_request_cb(hotplug_dev, &s->pcihp_state,
+                                            dev, errp);
     } else {
         error_setg(errp, "acpi: device unplug request for unsupported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -279,6 +296,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
         acpi_memory_unplug_cb(&s->memhp_state, dev, errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
         acpi_cpu_unplug_cb(&s->cpuhp_state, dev, errp);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        acpi_pcihp_device_unplug_cb(hotplug_dev, &s->pcihp_state, dev, errp);
     } else {
         error_setg(errp, "acpi: device unplug for unsupported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -495,6 +514,7 @@ static void acpi_ged_class_init(ObjectClass *class, const void *data)
     dc->vmsd = &vmstate_acpi_ged;
     dc->realize = acpi_ged_realize;
 
+    hc->pre_plug = acpi_ged_device_pre_plug_cb;
     hc->plug = acpi_ged_device_plug_cb;
     hc->unplug_request = acpi_ged_unplug_request_cb;
     hc->unplug = acpi_ged_unplug_cb;
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 18/22] hw/acpi/ged: Support migration of AcpiPciHpState
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (16 preceding siblings ...)
  2025-05-14 17:01 ` [PATCH 17/22] hw/acpi/ged: Call pcihp plug callbacks in hotplug handler implementation Eric Auger
@ 2025-05-14 17:01 ` Eric Auger
  2025-05-14 17:01 ` [PATCH 19/22] hw/core/sysbus: Introduce sysbus_mmio_map_name() helper Eric Auger
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:01 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Add a subsection to migrate the AcpiPciHpState state.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 hw/acpi/generic_event_device.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 519329e2ef..30751c2bcc 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -415,6 +415,25 @@ static const VMStateDescription vmstate_ghes_state = {
     }
 };
 
+static bool pcihp_needed(void *opaque)
+{
+    AcpiGedState *s = opaque;
+    return s->pcihp_state.use_acpi_hotplug_bridge;
+}
+
+static const VMStateDescription vmstate_pcihp_state = {
+    .name = "acpi-ged/pcihp",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = pcihp_needed,
+    .fields = (const VMStateField[]) {
+        VMSTATE_PCI_HOTPLUG(pcihp_state,
+                            AcpiGedState,
+                            NULL, NULL),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_acpi_ged = {
     .name = "acpi-ged",
     .version_id = 1,
@@ -427,6 +446,7 @@ static const VMStateDescription vmstate_acpi_ged = {
         &vmstate_memhp_state,
         &vmstate_cpuhp_state,
         &vmstate_ghes_state,
+        &vmstate_pcihp_state,
         NULL
     }
 };
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 19/22] hw/core/sysbus: Introduce sysbus_mmio_map_name() helper
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (17 preceding siblings ...)
  2025-05-14 17:01 ` [PATCH 18/22] hw/acpi/ged: Support migration of AcpiPciHpState Eric Auger
@ 2025-05-14 17:01 ` Eric Auger
  2025-05-14 17:01 ` [PATCH 20/22] hw/arm/virt: Let virt support pci hotplug/unplug GED event Eric Auger
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:01 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Some sysbus devices have conditionnal mmio regions. This
happens for instance with the hw/acpi/ged device. In that case
it becomes difficult to predict which index a specific MMIO
region corresponds to when one needs to mmio map the region.
Introduce a new helper that takes the name of the region instead
of its index. If the region is not found this returns -1.
Otherwise it maps the corresponding index and returns this latter.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/sysbus.h |  1 +
 hw/core/sysbus.c    | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h
index 7dc88aaa27..18fde8a7b4 100644
--- a/include/hw/sysbus.h
+++ b/include/hw/sysbus.h
@@ -82,6 +82,7 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
 bool sysbus_is_irq_connected(SysBusDevice *dev, int n);
 qemu_irq sysbus_get_connected_irq(SysBusDevice *dev, int n);
 void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr);
+int sysbus_mmio_map_name(SysBusDevice *dev, const char*name, hwaddr addr);
 void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr,
                              int priority);
 
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index e71367adfb..ec69e877a2 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -151,6 +151,17 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr)
     sysbus_mmio_map_common(dev, n, addr, false, 0);
 }
 
+int sysbus_mmio_map_name(SysBusDevice *dev, const char *name, hwaddr addr)
+{
+    for (int i = 0; i < dev->num_mmio; i++) {
+        if (!strcmp(dev->mmio[i].memory->name, name)) {
+            sysbus_mmio_map(dev, i, addr);
+            return i;
+        }
+    }
+    return -1;
+}
+
 void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr,
                              int priority)
 {
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 20/22] hw/arm/virt: Let virt support pci hotplug/unplug GED event
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (18 preceding siblings ...)
  2025-05-14 17:01 ` [PATCH 19/22] hw/core/sysbus: Introduce sysbus_mmio_map_name() helper Eric Auger
@ 2025-05-14 17:01 ` Eric Auger
  2025-05-14 17:01 ` [PATCH 21/22] hw/arm/virt: Plug pcihp hotplug/hotunplug callbacks Eric Auger
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:01 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Set up the IO registers used to communicate between QEMU
and ACPI.

Move the create_pcie() call after the creation of the acpi
ged device since hotplug callbacks will soon be called on gpex
realize and will require the acpi pcihp state to be initialized.

The hacky thing is the root bus has not yet been created on
acpi_pcihp_init() call so it is set later after the gpex realize.

How to fix this chicken & egg issue?

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 include/hw/arm/virt.h    |  1 +
 hw/arm/virt-acpi-build.c |  1 +
 hw/arm/virt.c            | 42 +++++++++++++++++++++++++++++++++++-----
 3 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 1b2e2e1284..a4c4e3a67a 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -35,6 +35,7 @@
 #include "hw/boards.h"
 #include "hw/arm/boot.h"
 #include "hw/arm/bsa.h"
+#include "hw/acpi/pcihp.h"
 #include "hw/block/flash.h"
 #include "system/kvm.h"
 #include "hw/intc/arm_gicv3_common.h"
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 2b642e2426..05a754d368 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -44,6 +44,7 @@
 #include "hw/acpi/generic_event_device.h"
 #include "hw/acpi/tpm.h"
 #include "hw/acpi/hmat.h"
+#include "hw/acpi/pcihp.h"
 #include "hw/pci/pcie_host.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bus.h"
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 4aa40c8e8b..526c4c44be 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -682,6 +682,8 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
 {
     DeviceState *dev;
     MachineState *ms = MACHINE(vms);
+    SysBusDevice *sbdev;
+
     int irq = vms->irqmap[VIRT_ACPI_GED];
     uint32_t event = ACPI_GED_PWR_DOWN_EVT;
 
@@ -693,12 +695,28 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
         event |= ACPI_GED_NVDIMM_HOTPLUG_EVT;
     }
 
+    if (vms->acpi_pcihp) {
+        event |= ACPI_GED_PCI_HOTPLUG_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);
+    sbdev = SYS_BUS_DEVICE(dev);
+    sysbus_realize_and_unref(sbdev, &error_fatal);
 
-    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
-    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
+    sysbus_mmio_map(sbdev, 0, vms->memmap[VIRT_ACPI_GED].base);
+    sysbus_mmio_map(sbdev, 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
+    if (vms->acpi_pcihp) {
+        AcpiGedState *acpi_ged_state = ACPI_GED(dev);
+        int i;
+
+        i = sysbus_mmio_map_name(sbdev, "pcihp container",
+                                 vms->memmap[VIRT_ACPI_PCIHP].base);
+        assert(i >= 0);
+        acpi_pcihp_init(OBJECT(dev), &acpi_ged_state->pcihp_state,
+                        vms->bus, sysbus_mmio_get_region(sbdev, i), 0);
+        acpi_ged_state->pcihp_state.use_acpi_hotplug_bridge = true;
+    }
     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
 
     return dev;
@@ -1758,6 +1776,13 @@ void virt_machine_done(Notifier *notifier, void *data)
     pci_bus_add_fw_cfg_extra_pci_roots(vms->fw_cfg, vms->bus,
                                        &error_abort);
 
+
+    if (vms->acpi_pcihp) {
+        AcpiGedState *acpi_ged_state = ACPI_GED(vms->acpi_dev);
+
+        acpi_pcihp_reset(&acpi_ged_state->pcihp_state);
+    }
+
     virt_acpi_setup(vms);
     virt_build_smbios(vms);
 }
@@ -2395,8 +2420,6 @@ static void machvirt_init(MachineState *machine)
 
     create_rtc(vms);
 
-    create_pcie(vms);
-
     if (has_ged && aarch64 && firmware_loaded && virt_is_acpi_enabled(vms)) {
         vms->acpi_pcihp &= !vmc->no_acpi_pcihp;
         vms->acpi_dev = create_acpi_ged(vms);
@@ -2405,6 +2428,15 @@ static void machvirt_init(MachineState *machine)
         create_gpio_devices(vms, VIRT_GPIO, sysmem);
     }
 
+    create_pcie(vms);
+
+    if (vms->acpi_dev) {
+        AcpiGedState *acpi_ged_state = ACPI_GED(vms->acpi_dev);
+
+        acpi_ged_state = ACPI_GED(vms->acpi_dev);
+        acpi_ged_state->pcihp_state.root = vms->bus;
+    }
+
     if (vms->secure && !vmc->no_secure_gpio) {
         create_gpio_devices(vms, VIRT_SECURE_GPIO, secure_sysmem);
     }
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 21/22] hw/arm/virt: Plug pcihp hotplug/hotunplug callbacks
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (19 preceding siblings ...)
  2025-05-14 17:01 ` [PATCH 20/22] hw/arm/virt: Let virt support pci hotplug/unplug GED event Eric Auger
@ 2025-05-14 17:01 ` Eric Auger
  2025-05-14 17:01 ` [PATCH 22/22] hw/arm/virt: Use ACPI PCI hotplug by default Eric Auger
  2025-05-26  5:55 ` [PATCH 00/22] ACPI PCI Hotplug support on ARM Gustavo Romero
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:01 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 hw/arm/virt.c | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 526c4c44be..ecbcc2200a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -87,6 +87,7 @@
 #include "hw/virtio/virtio-iommu.h"
 #include "hw/char/pl011.h"
 #include "qemu/guest-random.h"
+#include "hw/acpi/pcihp.h"
 
 static GlobalProperty arm_virt_compat[] = {
     { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
@@ -2973,6 +2974,11 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
         qlist_append_str(reserved_regions, resv_prop_str);
         qdev_prop_set_array(dev, "reserved-regions", reserved_regions);
         g_free(resv_prop_str);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        if (vms->acpi_pcihp) {
+            acpi_pcihp_device_pre_plug_cb(HOTPLUG_HANDLER(vms->acpi_dev),
+                                          dev, errp);
+        }
     }
 }
 
@@ -3002,6 +3008,14 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
         vms->iommu = VIRT_IOMMU_VIRTIO;
         vms->virtio_iommu_bdf = pci_get_bdf(pdev);
         create_virtio_iommu_dt_bindings(vms);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        AcpiGedState *acpi_ged_state = ACPI_GED(vms->acpi_dev);
+        AcpiPciHpState *acpi_pci_hotplug = &acpi_ged_state->pcihp_state;
+
+        if (vms->acpi_pcihp) {
+            acpi_pcihp_device_plug_cb(HOTPLUG_HANDLER(vms->acpi_dev),
+                                      acpi_pci_hotplug, dev, errp);
+        }
     }
 }
 
@@ -3051,6 +3065,15 @@ static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
         virtio_md_pci_unplug_request(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev),
                                      errp);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+        AcpiGedState *acpi_ged_state = ACPI_GED(vms->acpi_dev);
+        AcpiPciHpState *acpi_pci_hotplug = &acpi_ged_state->pcihp_state;
+
+        if (vms->acpi_pcihp) {
+            acpi_pcihp_device_unplug_request_cb(HOTPLUG_HANDLER(vms->acpi_dev),
+                                                acpi_pci_hotplug, dev, errp);
+        }
     } else {
         error_setg(errp, "device unplug request for unsupported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -3064,6 +3087,15 @@ static void virt_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
         virt_dimm_unplug(hotplug_dev, dev, errp);
     } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
         virtio_md_pci_unplug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+        AcpiGedState *acpi_ged_state = ACPI_GED(vms->acpi_dev);
+        AcpiPciHpState *acpi_pci_hotplug = &acpi_ged_state->pcihp_state;
+
+        if (vms->acpi_pcihp) {
+            acpi_pcihp_device_unplug_cb(HOTPLUG_HANDLER(vms->acpi_dev),
+                                        acpi_pci_hotplug, dev, errp);
+        }
     } else {
         error_setg(errp, "virt: device unplug for unsupported device"
                    " type: %s", object_get_typename(OBJECT(dev)));
@@ -3074,11 +3106,14 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
                                                         DeviceState *dev)
 {
     MachineClass *mc = MACHINE_GET_CLASS(machine);
+    VirtMachineState *vms = VIRT_MACHINE(machine);
 
     if (device_is_dynamic_sysbus(mc, dev) ||
         object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
         object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI) ||
-        object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
+        object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
+        (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE) &&
+                             vms->acpi_pcihp)) {
         return HOTPLUG_HANDLER(machine);
     }
     return NULL;
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH 22/22] hw/arm/virt: Use ACPI PCI hotplug by default
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (20 preceding siblings ...)
  2025-05-14 17:01 ` [PATCH 21/22] hw/arm/virt: Plug pcihp hotplug/hotunplug callbacks Eric Auger
@ 2025-05-14 17:01 ` Eric Auger
  2025-05-26  5:55 ` [PATCH 00/22] ACPI PCI Hotplug support on ARM Gustavo Romero
  22 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-14 17:01 UTC (permalink / raw)
  To: eric.auger.pro, eric.auger, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Now all the enablers are there for ACPI PCI hotplug support,
let's use it by default for 10.1 virt machine onwards.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
 hw/arm/virt.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index ecbcc2200a..abb0743af8 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3432,8 +3432,8 @@ static void virt_instance_init(Object *obj)
         vms->tcg_its = true;
     }
 
-    /* default disallows ACPI PCI hotplug */
-    vms->acpi_pcihp = false;
+    /* default allows ACPI PCI hotplug */
+    vms->acpi_pcihp = true;
 
     /* Default disallows iommu instantiation */
     vms->iommu = VIRT_IOMMU_NONE;
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH 01/22] hw/i386/acpi-build: Make aml_pci_device_dsm() static
  2025-05-14 17:00 ` [PATCH 01/22] hw/i386/acpi-build: Make aml_pci_device_dsm() static Eric Auger
@ 2025-05-20 12:30   ` Gustavo Romero
  2025-05-25 15:29   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 47+ messages in thread
From: Gustavo Romero @ 2025-05-20 12:30 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:00, Eric Auger wrote:
> No need to export aml_pci_device_dsm() as it is only used
> in hw/i386/acpi-build.c.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>   include/hw/acpi/pci.h | 1 -
>   hw/i386/acpi-build.c  | 2 +-
>   2 files changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h
> index 6359d574fd..ab0187a894 100644
> --- a/include/hw/acpi/pci.h
> +++ b/include/hw/acpi/pci.h
> @@ -36,7 +36,6 @@ typedef struct AcpiMcfgInfo {
>   
>   void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info,
>                   const char *oem_id, const char *oem_table_id);
> -Aml *aml_pci_device_dsm(void);
>   
>   void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
>   void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope);
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index f40ad062f9..9e584e69fd 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -338,7 +338,7 @@ build_facs(GArray *table_data)
>       g_array_append_vals(table_data, reserved, 40); /* Reserved */
>   }
>   
> -Aml *aml_pci_device_dsm(void)
> +static Aml *aml_pci_device_dsm(void)
>   {
>       Aml *method;
>   

Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>


Cheers,
Gustavo


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 03/22] hw/acpi: Rename and move build_x86_acpi_pci_hotplug to pcihp
  2025-05-14 17:00 ` [PATCH 03/22] hw/acpi: Rename and move build_x86_acpi_pci_hotplug to pcihp Eric Auger
@ 2025-05-20 12:31   ` Gustavo Romero
  0 siblings, 0 replies; 47+ messages in thread
From: Gustavo Romero @ 2025-05-20 12:31 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:00, Eric Auger wrote:
> We plan to reuse build_x86_acpi_pci_hotplug() implementation
> for ARM so let's move the code to generic pcihp.
> 
> Associated static aml_pci_pdsm() helper is also moved along.
> build_x86_acpi_pci_hotplug is renamed into build_acpi_pci_hotplug().
> 
> No code change intended.
> 
> Also fix the reference to  acpi_pci_hotplug.rst documentation

nit: double space       ----^

There is still one place where the ref is wrong, see below.


> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> 
> ---
> 
> rfc -> v1:
> - make build_append_pci_dsm_func0_common non static and move it to
>    pcihp
> ---
>   hw/i386/acpi-build.h    |   4 -
>   include/hw/acpi/pcihp.h |   9 +-
>   hw/acpi/pcihp.c         | 174 ++++++++++++++++++++++++++++++++++++++-
>   hw/i386/acpi-build.c    | 176 +---------------------------------------
>   4 files changed, 183 insertions(+), 180 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
> index 275ec058a1..8ba3c33e48 100644
> --- a/hw/i386/acpi-build.h
> +++ b/hw/i386/acpi-build.h
> @@ -5,10 +5,6 @@
>   
>   extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
>   
> -/* PCI Hot-plug registers' base. See docs/specs/acpi_pci_hotplug.rst */
> -#define ACPI_PCIHP_SEJ_BASE 0x8
> -#define ACPI_PCIHP_BNMR_BASE 0x10
> -
>   void acpi_setup(void);
>   Object *acpi_get_i386_pci_host(void);
>   
> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
> index a97904bada..95efe9a804 100644
> --- a/include/hw/acpi/pcihp.h
> +++ b/include/hw/acpi/pcihp.h
> @@ -3,7 +3,7 @@
>    *
>    * QEMU supports PCI hotplug via ACPI. This module
>    * implements the interface between QEMU and the ACPI BIOS.
> - * Interface specification - see docs/specs/acpi_pci_hotplug.txt
> + * Interface specification - see docs/specs/acpi_pci_hotplug.rst
>    *
>    * Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)
>    * Copyright (c) 2006 Fabrice Bellard
> @@ -33,6 +33,10 @@
>   #define ACPI_PCIHP_IO_BASE_PROP "acpi-pcihp-io-base"
>   #define ACPI_PCIHP_IO_LEN_PROP "acpi-pcihp-io-len"
>   
> +/* PCI Hot-plug registers bases. See docs/spec/acpi_pci_hotplug.rst */

nit:                               specs   ---^


Otherwise:

Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>


Cheers,
Gustavo

> +#define ACPI_PCIHP_SEJ_BASE 0x8
> +#define ACPI_PCIHP_BNMR_BASE 0x10
> +
>   typedef struct AcpiPciHpPciStatus {
>       uint32_t up;
>       uint32_t down;
> @@ -69,6 +73,9 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
>                                            AcpiPciHpState *s, DeviceState *dev,
>                                            Error **errp);
>   
> +void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr);
> +void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar);
> +
>   /* Called on reset */
>   void acpi_pcihp_reset(AcpiPciHpState *s);
>   
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index aac90013d4..e0260f67e6 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -26,7 +26,7 @@
>   
>   #include "qemu/osdep.h"
>   #include "hw/acpi/pcihp.h"
> -
> +#include "hw/acpi/aml-build.h"
>   #include "hw/pci-host/i440fx.h"
>   #include "hw/pci/pci.h"
>   #include "hw/pci/pci_bridge.h"
> @@ -513,6 +513,178 @@ void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
>                                      OBJ_PROP_FLAG_READ);
>   }
>   
> +void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar)
> +{
> +    Aml *UUID, *ifctx1;
> +    uint8_t byte_list[1] = { 0 }; /* nothing supported yet */
> +
> +    aml_append(ctx, aml_store(aml_buffer(1, byte_list), retvar));
> +    /*
> +     * PCI Firmware Specification 3.1
> +     * 4.6.  _DSM Definitions for PCI
> +     */
> +    UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
> +    ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(0), UUID)));
> +    {
> +        /* call is for unsupported UUID, bail out */
> +        aml_append(ifctx1, aml_return(retvar));
> +    }
> +    aml_append(ctx, ifctx1);
> +
> +    ifctx1 = aml_if(aml_lless(aml_arg(1), aml_int(2)));
> +    {
> +        /* call is for unsupported REV, bail out */
> +        aml_append(ifctx1, aml_return(retvar));
> +    }
> +    aml_append(ctx, ifctx1);
> +}
> +
> +static Aml *aml_pci_pdsm(void)
> +{
> +    Aml *method, *ifctx, *ifctx1;
> +    Aml *ret = aml_local(0);
> +    Aml *caps = aml_local(1);
> +    Aml *acpi_index = aml_local(2);
> +    Aml *zero = aml_int(0);
> +    Aml *one = aml_int(1);
> +    Aml *not_supp = aml_int(0xFFFFFFFF);
> +    Aml *func = aml_arg(2);
> +    Aml *params = aml_arg(4);
> +    Aml *bnum = aml_derefof(aml_index(params, aml_int(0)));
> +    Aml *sunum = aml_derefof(aml_index(params, aml_int(1)));
> +
> +    method = aml_method("PDSM", 5, AML_SERIALIZED);
> +
> +    /* get supported functions */
> +    ifctx = aml_if(aml_equal(func, zero));
> +    {
> +        build_append_pci_dsm_func0_common(ifctx, ret);
> +
> +        aml_append(ifctx, aml_store(zero, caps));
> +        aml_append(ifctx,
> +            aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
> +        /*
> +         * advertise function 7 if device has acpi-index
> +         * acpi_index values:
> +         *            0: not present (default value)
> +         *     FFFFFFFF: not supported (old QEMU without PIDX reg)
> +         *        other: device's acpi-index
> +         */
> +        ifctx1 = aml_if(aml_lnot(
> +                     aml_or(aml_equal(acpi_index, zero),
> +                            aml_equal(acpi_index, not_supp), NULL)
> +                 ));
> +        {
> +            /* have supported functions */
> +            aml_append(ifctx1, aml_or(caps, one, caps));
> +            /* support for function 7 */
> +            aml_append(ifctx1,
> +                aml_or(caps, aml_shiftleft(one, aml_int(7)), caps));
> +        }
> +        aml_append(ifctx, ifctx1);
> +
> +        aml_append(ifctx, aml_store(caps, aml_index(ret, zero)));
> +        aml_append(ifctx, aml_return(ret));
> +    }
> +    aml_append(method, ifctx);
> +
> +    /* handle specific functions requests */
> +    /*
> +     * PCI Firmware Specification 3.1
> +     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
> +     *        Operating Systems
> +     */
> +    ifctx = aml_if(aml_equal(func, aml_int(7)));
> +    {
> +       Aml *pkg = aml_package(2);
> +
> +       aml_append(ifctx, aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
> +       aml_append(ifctx, aml_store(pkg, ret));
> +       /*
> +        * Windows calls func=7 without checking if it's available,
> +        * as workaround Microsoft has suggested to return invalid for func7
> +        * Package, so return 2 elements package but only initialize elements
> +        * when acpi_index is supported and leave them uninitialized, which
> +        * leads elements to being Uninitialized ObjectType and should trip
> +        * Windows into discarding result as an unexpected and prevent setting
> +        * bogus 'PCI Label' on the device.
> +        */
> +       ifctx1 = aml_if(aml_lnot(aml_lor(
> +                    aml_equal(acpi_index, zero), aml_equal(acpi_index, not_supp)
> +                )));
> +       {
> +           aml_append(ifctx1, aml_store(acpi_index, aml_index(ret, zero)));
> +           /*
> +            * optional, if not impl. should return null string
> +            */
> +           aml_append(ifctx1, aml_store(aml_string("%s", ""),
> +                                        aml_index(ret, one)));
> +       }
> +       aml_append(ifctx, ifctx1);
> +
> +       aml_append(ifctx, aml_return(ret));
> +    }
> +
> +    aml_append(method, ifctx);
> +    return method;
> +}
> +
> +void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr)
> +{
> +    Aml *scope;
> +    Aml *field;
> +    Aml *method;
> +
> +    scope =  aml_scope("_SB.PCI0");
> +
> +    aml_append(scope,
> +        aml_operation_region("PCST", AML_SYSTEM_IO, aml_int(pcihp_addr), 0x08));
> +    field = aml_field("PCST", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
> +    aml_append(field, aml_named_field("PCIU", 32));
> +    aml_append(field, aml_named_field("PCID", 32));
> +    aml_append(scope, field);
> +
> +    aml_append(scope,
> +        aml_operation_region("SEJ", AML_SYSTEM_IO,
> +                             aml_int(pcihp_addr + ACPI_PCIHP_SEJ_BASE), 0x04));
> +    field = aml_field("SEJ", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
> +    aml_append(field, aml_named_field("B0EJ", 32));
> +    aml_append(scope, field);
> +
> +    aml_append(scope,
> +        aml_operation_region("BNMR", AML_SYSTEM_IO,
> +                             aml_int(pcihp_addr + ACPI_PCIHP_BNMR_BASE), 0x08));
> +    field = aml_field("BNMR", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
> +    aml_append(field, aml_named_field("BNUM", 32));
> +    aml_append(field, aml_named_field("PIDX", 32));
> +    aml_append(scope, field);
> +
> +    aml_append(scope, aml_mutex("BLCK", 0));
> +
> +        method = aml_method("PCEJ", 2, AML_NOTSERIALIZED);
> +    aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
> +    aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
> +    aml_append(method,
> +        aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("B0EJ")));
> +    aml_append(method, aml_release(aml_name("BLCK")));
> +    aml_append(method, aml_return(aml_int(0)));
> +    aml_append(scope, method);
> +
> +    method = aml_method("AIDX", 2, AML_NOTSERIALIZED);
> +    aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
> +    aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
> +    aml_append(method,
> +        aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("PIDX")));
> +    aml_append(method, aml_store(aml_name("PIDX"), aml_local(0)));
> +    aml_append(method, aml_release(aml_name("BLCK")));
> +    aml_append(method, aml_return(aml_local(0)));
> +    aml_append(scope, method);
> +
> +    aml_append(scope, aml_pci_pdsm());
> +
> +    aml_append(table, scope);
> +}
> +
>   const VMStateDescription vmstate_acpi_pcihp_pci_status = {
>       .name = "acpi_pcihp_pci_status",
>       .version_id = 1,
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 9e584e69fd..b92765fbd9 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -361,32 +361,6 @@ static Aml *aml_pci_device_dsm(void)
>       return method;
>   }
>   
> -static void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar)
> -{
> -    Aml *UUID, *ifctx1;
> -    uint8_t byte_list[1] = { 0 }; /* nothing supported yet */
> -
> -    aml_append(ctx, aml_store(aml_buffer(1, byte_list), retvar));
> -    /*
> -     * PCI Firmware Specification 3.1
> -     * 4.6.  _DSM Definitions for PCI
> -     */
> -    UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
> -    ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(0), UUID)));
> -    {
> -        /* call is for unsupported UUID, bail out */
> -        aml_append(ifctx1, aml_return(retvar));
> -    }
> -    aml_append(ctx, ifctx1);
> -
> -    ifctx1 = aml_if(aml_lless(aml_arg(1), aml_int(2)));
> -    {
> -        /* call is for unsupported REV, bail out */
> -        aml_append(ifctx1, aml_return(retvar));
> -    }
> -    aml_append(ctx, ifctx1);
> -}
> -
>   static Aml *aml_pci_edsm(void)
>   {
>       Aml *method, *ifctx;
> @@ -647,96 +621,6 @@ static bool build_append_notification_callback(Aml *parent_scope,
>       return !!nr_notifiers;
>   }
>   
> -static Aml *aml_pci_pdsm(void)
> -{
> -    Aml *method, *ifctx, *ifctx1;
> -    Aml *ret = aml_local(0);
> -    Aml *caps = aml_local(1);
> -    Aml *acpi_index = aml_local(2);
> -    Aml *zero = aml_int(0);
> -    Aml *one = aml_int(1);
> -    Aml *not_supp = aml_int(0xFFFFFFFF);
> -    Aml *func = aml_arg(2);
> -    Aml *params = aml_arg(4);
> -    Aml *bnum = aml_derefof(aml_index(params, aml_int(0)));
> -    Aml *sunum = aml_derefof(aml_index(params, aml_int(1)));
> -
> -    method = aml_method("PDSM", 5, AML_SERIALIZED);
> -
> -    /* get supported functions */
> -    ifctx = aml_if(aml_equal(func, zero));
> -    {
> -        build_append_pci_dsm_func0_common(ifctx, ret);
> -
> -        aml_append(ifctx, aml_store(zero, caps));
> -        aml_append(ifctx,
> -            aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
> -        /*
> -         * advertise function 7 if device has acpi-index
> -         * acpi_index values:
> -         *            0: not present (default value)
> -         *     FFFFFFFF: not supported (old QEMU without PIDX reg)
> -         *        other: device's acpi-index
> -         */
> -        ifctx1 = aml_if(aml_lnot(
> -                     aml_or(aml_equal(acpi_index, zero),
> -                            aml_equal(acpi_index, not_supp), NULL)
> -                 ));
> -        {
> -            /* have supported functions */
> -            aml_append(ifctx1, aml_or(caps, one, caps));
> -            /* support for function 7 */
> -            aml_append(ifctx1,
> -                aml_or(caps, aml_shiftleft(one, aml_int(7)), caps));
> -        }
> -        aml_append(ifctx, ifctx1);
> -
> -        aml_append(ifctx, aml_store(caps, aml_index(ret, zero)));
> -        aml_append(ifctx, aml_return(ret));
> -    }
> -    aml_append(method, ifctx);
> -
> -    /* handle specific functions requests */
> -    /*
> -     * PCI Firmware Specification 3.1
> -     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
> -     *        Operating Systems
> -     */
> -    ifctx = aml_if(aml_equal(func, aml_int(7)));
> -    {
> -       Aml *pkg = aml_package(2);
> -
> -       aml_append(ifctx, aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
> -       aml_append(ifctx, aml_store(pkg, ret));
> -       /*
> -        * Windows calls func=7 without checking if it's available,
> -        * as workaround Microsoft has suggested to return invalid for func7
> -        * Package, so return 2 elements package but only initialize elements
> -        * when acpi_index is supported and leave them uninitialized, which
> -        * leads elements to being Uninitialized ObjectType and should trip
> -        * Windows into discarding result as an unexpected and prevent setting
> -        * bogus 'PCI Label' on the device.
> -        */
> -       ifctx1 = aml_if(aml_lnot(aml_lor(
> -                    aml_equal(acpi_index, zero), aml_equal(acpi_index, not_supp)
> -                )));
> -       {
> -           aml_append(ifctx1, aml_store(acpi_index, aml_index(ret, zero)));
> -           /*
> -            * optional, if not impl. should return null string
> -            */
> -           aml_append(ifctx1, aml_store(aml_string("%s", ""),
> -                                        aml_index(ret, one)));
> -       }
> -       aml_append(ifctx, ifctx1);
> -
> -       aml_append(ifctx, aml_return(ret));
> -    }
> -
> -    aml_append(method, ifctx);
> -    return method;
> -}
> -
>   /*
>    * build_prt - Define interrupt routing rules
>    *
> @@ -1227,62 +1111,6 @@ static Aml *build_q35_dram_controller(const AcpiMcfgInfo *mcfg)
>       return dev;
>   }
>   
> -static void build_x86_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr)
> -{
> -    Aml *scope;
> -    Aml *field;
> -    Aml *method;
> -
> -    scope =  aml_scope("_SB.PCI0");
> -
> -    aml_append(scope,
> -        aml_operation_region("PCST", AML_SYSTEM_IO, aml_int(pcihp_addr), 0x08));
> -    field = aml_field("PCST", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
> -    aml_append(field, aml_named_field("PCIU", 32));
> -    aml_append(field, aml_named_field("PCID", 32));
> -    aml_append(scope, field);
> -
> -    aml_append(scope,
> -        aml_operation_region("SEJ", AML_SYSTEM_IO,
> -                             aml_int(pcihp_addr + ACPI_PCIHP_SEJ_BASE), 0x04));
> -    field = aml_field("SEJ", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
> -    aml_append(field, aml_named_field("B0EJ", 32));
> -    aml_append(scope, field);
> -
> -    aml_append(scope,
> -        aml_operation_region("BNMR", AML_SYSTEM_IO,
> -                             aml_int(pcihp_addr + ACPI_PCIHP_BNMR_BASE), 0x08));
> -    field = aml_field("BNMR", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
> -    aml_append(field, aml_named_field("BNUM", 32));
> -    aml_append(field, aml_named_field("PIDX", 32));
> -    aml_append(scope, field);
> -
> -    aml_append(scope, aml_mutex("BLCK", 0));
> -
> -    method = aml_method("PCEJ", 2, AML_NOTSERIALIZED);
> -    aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
> -    aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
> -    aml_append(method,
> -        aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("B0EJ")));
> -    aml_append(method, aml_release(aml_name("BLCK")));
> -    aml_append(method, aml_return(aml_int(0)));
> -    aml_append(scope, method);
> -
> -    method = aml_method("AIDX", 2, AML_NOTSERIALIZED);
> -    aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
> -    aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
> -    aml_append(method,
> -        aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("PIDX")));
> -    aml_append(method, aml_store(aml_name("PIDX"), aml_local(0)));
> -    aml_append(method, aml_release(aml_name("BLCK")));
> -    aml_append(method, aml_return(aml_local(0)));
> -    aml_append(scope, method);
> -
> -    aml_append(scope, aml_pci_pdsm());
> -
> -    aml_append(table, scope);
> -}
> -
>   static Aml *build_q35_osc_method(bool enable_native_pcie_hotplug)
>   {
>       Aml *if_ctx;
> @@ -1394,7 +1222,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>           aml_append(dsdt, sb_scope);
>   
>           if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
> -            build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
> +            build_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
>           }
>           build_piix4_pci0_int(dsdt);
>       } else if (q35) {
> @@ -1438,7 +1266,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>           aml_append(dsdt, sb_scope);
>   
>           if (pm->pcihp_bridge_en) {
> -            build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
> +            build_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
>           }
>           build_q35_pci0_int(dsdt);
>       }



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 07/22] hw/i386/acpi-build: Turn build_q35_osc_method into a generic method
  2025-05-14 17:00 ` [PATCH 07/22] hw/i386/acpi-build: Turn build_q35_osc_method into a generic method Eric Auger
@ 2025-05-20 12:59   ` Gustavo Romero
  0 siblings, 0 replies; 47+ messages in thread
From: Gustavo Romero @ 2025-05-20 12:59 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:00, Eric Auger wrote:
> GPEX acpi_dsdt_add_pci_osc() does basically the same as
> build_q35_osc_method().
> 
> Rename build_q35_osc_method() into build_pci_host_bridge_osc_method()
> and move it into hw/acpi/aml-build.c. In a subsequent patch we will
> use this later in place of acpi_dsdt_add_pci_osc().
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>

Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>


Cheers,
Gustavo

> ---
>   include/hw/acpi/aml-build.h |  2 ++
>   hw/acpi/aml-build.c         | 50 ++++++++++++++++++++++++++++++++++
>   hw/i386/acpi-build.c        | 54 ++-----------------------------------
>   3 files changed, 54 insertions(+), 52 deletions(-)
> 
> diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
> index c18f681342..177d60b414 100644
> --- a/include/hw/acpi/aml-build.h
> +++ b/include/hw/acpi/aml-build.h
> @@ -508,4 +508,6 @@ void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
>   void build_spcr(GArray *table_data, BIOSLinker *linker,
>                   const AcpiSpcrData *f, const uint8_t rev,
>                   const char *oem_id, const char *oem_table_id, const char *name);
> +
> +Aml *build_pci_host_bridge_osc_method(bool enable_native_pcie_hotplug);
>   #endif
> diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> index f8f93a9f66..ba1dfe0b52 100644
> --- a/hw/acpi/aml-build.c
> +++ b/hw/acpi/aml-build.c
> @@ -2614,3 +2614,53 @@ Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source)
>   
>       return var;
>   }
> +
> +Aml *build_pci_host_bridge_osc_method(bool enable_native_pcie_hotplug)
> +{
> +    Aml *if_ctx;
> +    Aml *if_ctx2;
> +    Aml *else_ctx;
> +    Aml *method;
> +    Aml *a_cwd1 = aml_name("CDW1");
> +    Aml *a_ctrl = aml_local(0);
> +
> +    method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
> +    aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
> +
> +    if_ctx = aml_if(aml_equal(
> +        aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766")));
> +    aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
> +    aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
> +
> +    aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl));
> +
> +    /*
> +     * Always allow native PME, AER (no dependencies)
> +     * Allow SHPC (PCI bridges can have SHPC controller)
> +     * Disable PCIe Native Hot-plug if ACPI PCI Hot-plug is enabled.
> +     */
> +    aml_append(if_ctx, aml_and(a_ctrl,
> +        aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)), a_ctrl));
> +
> +    if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
> +    /* Unknown revision */
> +    aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1));
> +    aml_append(if_ctx, if_ctx2);
> +
> +    if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl)));
> +    /* Capabilities bits were masked */
> +    aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1));
> +    aml_append(if_ctx, if_ctx2);
> +
> +    /* Update DWORD3 in the buffer */
> +    aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3")));
> +    aml_append(method, if_ctx);
> +
> +    else_ctx = aml_else();
> +    /* Unrecognized UUID */
> +    aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1));
> +    aml_append(method, else_ctx);
> +
> +    aml_append(method, aml_return(aml_arg(3)));
> +    return method;
> +}
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index b92765fbd9..41fde88b22 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -1111,56 +1111,6 @@ static Aml *build_q35_dram_controller(const AcpiMcfgInfo *mcfg)
>       return dev;
>   }
>   
> -static Aml *build_q35_osc_method(bool enable_native_pcie_hotplug)
> -{
> -    Aml *if_ctx;
> -    Aml *if_ctx2;
> -    Aml *else_ctx;
> -    Aml *method;
> -    Aml *a_cwd1 = aml_name("CDW1");
> -    Aml *a_ctrl = aml_local(0);
> -
> -    method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
> -    aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
> -
> -    if_ctx = aml_if(aml_equal(
> -        aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766")));
> -    aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
> -    aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
> -
> -    aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl));
> -
> -    /*
> -     * Always allow native PME, AER (no dependencies)
> -     * Allow SHPC (PCI bridges can have SHPC controller)
> -     * Disable PCIe Native Hot-plug if ACPI PCI Hot-plug is enabled.
> -     */
> -    aml_append(if_ctx, aml_and(a_ctrl,
> -        aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)), a_ctrl));
> -
> -    if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
> -    /* Unknown revision */
> -    aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1));
> -    aml_append(if_ctx, if_ctx2);
> -
> -    if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl)));
> -    /* Capabilities bits were masked */
> -    aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1));
> -    aml_append(if_ctx, if_ctx2);
> -
> -    /* Update DWORD3 in the buffer */
> -    aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3")));
> -    aml_append(method, if_ctx);
> -
> -    else_ctx = aml_else();
> -    /* Unrecognized UUID */
> -    aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1));
> -    aml_append(method, else_ctx);
> -
> -    aml_append(method, aml_return(aml_arg(3)));
> -    return method;
> -}
> -
>   static void build_acpi0017(Aml *table)
>   {
>       Aml *dev, *scope, *method;
> @@ -1231,7 +1181,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>           aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
>           aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
>           aml_append(dev, aml_name_decl("_UID", aml_int(pcmc->pci_root_uid)));
> -        aml_append(dev, build_q35_osc_method(!pm->pcihp_bridge_en));
> +        aml_append(dev, build_pci_host_bridge_osc_method(!pm->pcihp_bridge_en));
>           aml_append(dev, aml_pci_edsm());
>           aml_append(sb_scope, dev);
>           if (mcfg_valid) {
> @@ -1353,7 +1303,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>                   aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
>   
>                   /* Expander bridges do not have ACPI PCI Hot-plug enabled */
> -                aml_append(dev, build_q35_osc_method(true));
> +                aml_append(dev, build_pci_host_bridge_osc_method(true));
>               } else {
>                   aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
>               }



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 08/22] hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method
  2025-05-14 17:00 ` [PATCH 08/22] hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method Eric Auger
@ 2025-05-20 14:09   ` Gustavo Romero
  2025-05-21 16:12     ` Eric Auger
  0 siblings, 1 reply; 47+ messages in thread
From: Gustavo Romero @ 2025-05-20 14:09 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:00, Eric Auger wrote:
> gpex build_host_bridge_osc() and x86 originated
> build_pci_host_bridge_osc_method() are mostly identical.
> 
> In GPEX, SUPP is set to CDW2 but is not further used. CTRL
> is same as Local0.
> 
> So let gpex code reuse build_pci_host_bridge_osc_method()
> and remove build_host_bridge_osc().
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> 
> ---
> 
> The DSDT diff  is given below:
> diff --git a/dsdt.dsl_before b/dsdt.dsl_after_osc_change
> index 3224a56..fa7558e 100644
> --- a/dsdt.dsl_before
> +++ b/dsdt.dsl_after_osc_change
> @@ -5,13 +5,13 @@
>    *
>    * Disassembling to symbolic ASL+ operators
>    *
> - * Disassembly of dsdt.dat, Mon Apr  7 05:33:06 2025
> + * Disassembly of dsdt.dat, Mon Apr  7 05:37:20 2025
>    *
>    * Original Table Header:
>    *     Signature        "DSDT"
> - *     Length           0x00001A4F (6735)
> + *     Length           0x00001A35 (6709)
>    *     Revision         0x02
> - *     Checksum         0xBF
> + *     Checksum         0xDD
>    *     OEM ID           "BOCHS "
>    *     OEM Table ID     "BXPC    "
>    *     OEM Revision     0x00000001 (1)
> @@ -1849,27 +1849,26 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPC    ", 0x00000001)
>                   {
>                       CreateDWordField (Arg3, 0x04, CDW2)
>                       CreateDWordField (Arg3, 0x08, CDW3)
> -                    SUPP = CDW2 /* \_SB_.PCI0._OSC.CDW2 */
> -                    CTRL = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
> -                    CTRL &= 0x1F
> +                    Local0 = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
> +                    Local0 &= 0x1F
>                       If ((Arg1 != One))
>                       {
>                           CDW1 |= 0x08
>                       }
> 
> -                    If ((CDW3 != CTRL))
> +                    If ((CDW3 != Local0))
>                       {
>                           CDW1 |= 0x10
>                       }
> 
> -                    CDW3 = CTRL /* \_SB_.PCI0.CTRL */
> -                    Return (Arg3)
> +                    CDW3 = Local0
>                   }
>                   Else
>                   {
>                       CDW1 |= 0x04
> -                    Return (Arg3)
>                   }
> +
> +                Return (Arg3)
>               }
> 
>               Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method

The problem I face with diffs in the commit body is that tools like b4, which are
based on git am, get very confused on how to handle it. I'm surprised nobody ever
complained about it. I'm wondering if there is any catch on it, because I have to
edit commits like this manually, removing the diff, to make it finally apply to
the series. Anyways, do you mind at least removing the valid diff header, like:

> diff --git a/dsdt.dsl_before b/dsdt.dsl_after_osc_change
> index 3224a56..fa7558e 100644
> --- a/dsdt.dsl_before
> +++ b/dsdt.dsl_after_osc_change

from the commit message so it doesn't confuse b4?


> ---
>   hw/pci-host/gpex-acpi.c | 60 +++--------------------------------------
>   1 file changed, 4 insertions(+), 56 deletions(-)
> 
> diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
> index f1ab30f3d5..98c9868c3f 100644
> --- a/hw/pci-host/gpex-acpi.c
> +++ b/hw/pci-host/gpex-acpi.c
> @@ -50,60 +50,7 @@ static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq,
>       }
>   }
>   
> -static Aml *build_host_bridge_osc(bool enable_native_pcie_hotplug)
> -{
> -    Aml *method, *UUID, *ifctx, *ifctx1, *elsectx;
> -
> -    method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
> -    aml_append(method,
> -        aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
> -
> -    /* PCI Firmware Specification 3.0
> -     * 4.5.1. _OSC Interface for PCI Host Bridge Devices
> -     * The _OSC interface for a PCI/PCI-X/PCI Express hierarchy is
> -     * identified by the Universal Unique IDentifier (UUID)
> -     * 33DB4D5B-1FF7-401C-9657-7441C03DD766
> -     */
> -    UUID = aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766");
> -    ifctx = aml_if(aml_equal(aml_arg(0), UUID));
> -    aml_append(ifctx,
> -        aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
> -    aml_append(ifctx,
> -        aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
> -    aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
> -    aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
> -
> -    /*
> -     * Allow OS control for SHPCHotplug, PME, AER, PCIeCapability,
> -     * and PCIeHotplug depending on enable_native_pcie_hotplug
> -     */
> -    aml_append(ifctx, aml_and(aml_name("CTRL"),
> -               aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)),
> -               aml_name("CTRL")));
> -
> -    ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
> -    aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
> -                              aml_name("CDW1")));
> -    aml_append(ifctx, ifctx1);
> -
> -    ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL"))));
> -    aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10),
> -                              aml_name("CDW1")));
> -    aml_append(ifctx, ifctx1);
> -
> -    aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
> -    aml_append(ifctx, aml_return(aml_arg(3)));
> -    aml_append(method, ifctx);
> -
> -    elsectx = aml_else();
> -    aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4),
> -                               aml_name("CDW1")));
> -    aml_append(elsectx, aml_return(aml_arg(3)));
> -    aml_append(method, elsectx);
> -    return method;
> -}
> -
> -static Aml *build_host_bridge_dsm(void)
> +static Aml *build_pci_host_bridge_dsm_method(void)
>   {
>       Aml *method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
>       Aml *UUID, *ifctx, *ifctx1, *buf;
> @@ -134,8 +81,9 @@ static void acpi_dsdt_add_host_bridge_methods(Aml *dev,
>       aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
>       aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
>       /* Declare an _OSC (OS Control Handoff) method */
> -    aml_append(dev, build_host_bridge_osc(enable_native_pcie_hotplug));
> -    aml_append(dev, build_host_bridge_dsm());
> +    aml_append(dev,
> +               build_pci_host_bridge_osc_method(enable_native_pcie_hotplug));
> +    aml_append(dev, build_pci_host_bridge_dsm_method());
>   }
>   
>   void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)

Otherwise:

Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>


Cheers,
Gustavo


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 09/22] hw/i386/acpi-build: Introduce build_append_pcihp_resources() helper
  2025-05-14 17:00 ` [PATCH 09/22] hw/i386/acpi-build: Introduce build_append_pcihp_resources() helper Eric Auger
@ 2025-05-20 18:57   ` Gustavo Romero
  0 siblings, 0 replies; 47+ messages in thread
From: Gustavo Romero @ 2025-05-20 18:57 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:00, Eric Auger wrote:
> Extract the code that reserves resources for ACPI PCI hotplug
> into a new helper named build_append_pcihp_resources() and
> move it to pcihp.c. We will reuse it on ARM.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>   include/hw/acpi/pcihp.h |  2 ++
>   hw/acpi/pcihp.c         | 20 ++++++++++++++++++++
>   hw/i386/acpi-build.c    | 15 ++-------------
>   3 files changed, 24 insertions(+), 13 deletions(-)

Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>


Cheers,
Gustavo

> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
> index 95efe9a804..ec9b010e4a 100644
> --- a/include/hw/acpi/pcihp.h
> +++ b/include/hw/acpi/pcihp.h
> @@ -75,6 +75,8 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
>   
>   void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr);
>   void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar);
> +void build_append_pcihp_resources(Aml *table,
> +                                  uint64_t io_addr, uint64_t io_len);
>   
>   /* Called on reset */
>   void acpi_pcihp_reset(AcpiPciHpState *s);
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index e0260f67e6..fb54c31f77 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -685,6 +685,26 @@ void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr)
>       aml_append(table, scope);
>   }
>   
> +/* Reserve PCIHP resources */
> +void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
> +                                  uint64_t io_addr, uint64_t io_len)
> +{
> +    Aml *dev, *crs;
> +
> +    dev = aml_device("PHPR");
> +    aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
> +    aml_append(dev,
> +               aml_name_decl("_UID", aml_string("PCI Hotplug resources")));
> +    /* device present, functioning, decoding, not shown in UI */
> +    aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
> +    crs = aml_resource_template();
> +    aml_append(crs,
> +        aml_io(AML_DECODE16, io_addr, io_addr, 1, io_len)
> +    );
> +    aml_append(dev, aml_name_decl("_CRS", crs));
> +    aml_append(scope, dev);
> +}
> +
>   const VMStateDescription vmstate_acpi_pcihp_pci_status = {
>       .name = "acpi_pcihp_pci_status",
>       .version_id = 1,
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 41fde88b22..ca59185aac 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -1432,19 +1432,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>   
>       /* reserve PCIHP resources */
>       if (pm->pcihp_io_len && (pm->pcihp_bridge_en || pm->pcihp_root_en)) {
> -        dev = aml_device("PHPR");
> -        aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
> -        aml_append(dev,
> -            aml_name_decl("_UID", aml_string("PCI Hotplug resources")));
> -        /* device present, functioning, decoding, not shown in UI */
> -        aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
> -        crs = aml_resource_template();
> -        aml_append(crs,
> -            aml_io(AML_DECODE16, pm->pcihp_io_base, pm->pcihp_io_base, 1,
> -                   pm->pcihp_io_len)
> -        );
> -        aml_append(dev, aml_name_decl("_CRS", crs));
> -        aml_append(scope, dev);
> +        build_append_pcihp_resources(scope,
> +                                      pm->pcihp_io_base, pm->pcihp_io_len);
>       }
>       aml_append(dsdt, scope);
>   



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 10/22] hw/acpi/pcihp: Add an AmlRegionSpace arg to build_acpi_pci_hotplug
  2025-05-14 17:00 ` [PATCH 10/22] hw/acpi/pcihp: Add an AmlRegionSpace arg to build_acpi_pci_hotplug Eric Auger
@ 2025-05-20 18:58   ` Gustavo Romero
  0 siblings, 0 replies; 47+ messages in thread
From: Gustavo Romero @ 2025-05-20 18:58 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:00, Eric Auger wrote:
> On ARM we will put the operation regions in AML_SYSTEM_MEMORY.
> So let's allow this configuration.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>   include/hw/acpi/pcihp.h | 3 ++-
>   hw/acpi/pcihp.c         | 8 ++++----
>   hw/i386/acpi-build.c    | 4 ++--
>   3 files changed, 8 insertions(+), 7 deletions(-)

Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>


Cheers,
Gustavo

> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
> index ec9b010e4a..525e61a2a9 100644
> --- a/include/hw/acpi/pcihp.h
> +++ b/include/hw/acpi/pcihp.h
> @@ -28,6 +28,7 @@
>   #define HW_ACPI_PCIHP_H
>   
>   #include "hw/acpi/acpi.h"
> +#include "hw/acpi/aml-build.h"
>   #include "hw/hotplug.h"
>   
>   #define ACPI_PCIHP_IO_BASE_PROP "acpi-pcihp-io-base"
> @@ -73,7 +74,7 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
>                                            AcpiPciHpState *s, DeviceState *dev,
>                                            Error **errp);
>   
> -void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr);
> +void build_acpi_pci_hotplug(Aml *table, AmlRegionSpace rs, uint64_t pcihp_addr);
>   void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar);
>   void build_append_pcihp_resources(Aml *table,
>                                     uint64_t io_addr, uint64_t io_len);
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index fb54c31f77..310a5c54bd 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -629,7 +629,7 @@ static Aml *aml_pci_pdsm(void)
>       return method;
>   }
>   
> -void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr)
> +void build_acpi_pci_hotplug(Aml *table, AmlRegionSpace rs, uint64_t pcihp_addr)
>   {
>       Aml *scope;
>       Aml *field;
> @@ -638,21 +638,21 @@ void build_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr)
>       scope =  aml_scope("_SB.PCI0");
>   
>       aml_append(scope,
> -        aml_operation_region("PCST", AML_SYSTEM_IO, aml_int(pcihp_addr), 0x08));
> +        aml_operation_region("PCST", rs, aml_int(pcihp_addr), 0x08));
>       field = aml_field("PCST", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
>       aml_append(field, aml_named_field("PCIU", 32));
>       aml_append(field, aml_named_field("PCID", 32));
>       aml_append(scope, field);
>   
>       aml_append(scope,
> -        aml_operation_region("SEJ", AML_SYSTEM_IO,
> +        aml_operation_region("SEJ", rs,
>                                aml_int(pcihp_addr + ACPI_PCIHP_SEJ_BASE), 0x04));
>       field = aml_field("SEJ", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
>       aml_append(field, aml_named_field("B0EJ", 32));
>       aml_append(scope, field);
>   
>       aml_append(scope,
> -        aml_operation_region("BNMR", AML_SYSTEM_IO,
> +        aml_operation_region("BNMR", rs,
>                                aml_int(pcihp_addr + ACPI_PCIHP_BNMR_BASE), 0x08));
>       field = aml_field("BNMR", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
>       aml_append(field, aml_named_field("BNUM", 32));
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index ca59185aac..87bb3d5cee 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -1172,7 +1172,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>           aml_append(dsdt, sb_scope);
>   
>           if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
> -            build_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
> +            build_acpi_pci_hotplug(dsdt, AML_SYSTEM_IO, pm->pcihp_io_base);
>           }
>           build_piix4_pci0_int(dsdt);
>       } else if (q35) {
> @@ -1216,7 +1216,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>           aml_append(dsdt, sb_scope);
>   
>           if (pm->pcihp_bridge_en) {
> -            build_acpi_pci_hotplug(dsdt, pm->pcihp_io_base);
> +            build_acpi_pci_hotplug(dsdt, AML_SYSTEM_IO, pm->pcihp_io_base);
>           }
>           build_q35_pci0_int(dsdt);
>       }



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 11/22] hw/i386/acpi-build: Move build_append_notification_callback to pcihp
  2025-05-14 17:00 ` [PATCH 11/22] hw/i386/acpi-build: Move build_append_notification_callback to pcihp Eric Auger
@ 2025-05-20 18:58   ` Gustavo Romero
  0 siblings, 0 replies; 47+ messages in thread
From: Gustavo Romero @ 2025-05-20 18:58 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:00, Eric Auger wrote:
> We plan to reuse build_append_notification_callback() on ARM
> so let's move it to pcihp.c.
> 
> No functional change intended.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>   include/hw/acpi/pcihp.h |  1 +
>   hw/acpi/pcihp.c         | 58 +++++++++++++++++++++++++++++++++++++++++
>   hw/i386/acpi-build.c    | 58 -----------------------------------------
>   3 files changed, 59 insertions(+), 58 deletions(-)

Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>


Cheers,
Gustavo

> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
> index 525e61a2a9..7c5d59243f 100644
> --- a/include/hw/acpi/pcihp.h
> +++ b/include/hw/acpi/pcihp.h
> @@ -78,6 +78,7 @@ void build_acpi_pci_hotplug(Aml *table, AmlRegionSpace rs, uint64_t pcihp_addr);
>   void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar);
>   void build_append_pcihp_resources(Aml *table,
>                                     uint64_t io_addr, uint64_t io_len);
> +bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus);
>   
>   /* Called on reset */
>   void acpi_pcihp_reset(AcpiPciHpState *s);
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index 310a5c54bd..907a08ac7f 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -39,6 +39,7 @@
>   #include "migration/vmstate.h"
>   #include "qapi/error.h"
>   #include "qom/qom-qobject.h"
> +#include "qobject/qnum.h"
>   #include "trace.h"
>   
>   #define ACPI_PCIHP_SIZE 0x0018
> @@ -705,6 +706,63 @@ void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
>       aml_append(scope, dev);
>   }
>   
> +bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus)
> +{
> +    Aml *method;
> +    PCIBus *sec;
> +    QObject *bsel;
> +    int nr_notifiers = 0;
> +    GQueue *pcnt_bus_list = g_queue_new();
> +
> +    QLIST_FOREACH(sec, &bus->child, sibling) {
> +        Aml *br_scope = aml_scope("S%.02X", sec->parent_dev->devfn);
> +        if (pci_bus_is_root(sec)) {
> +            continue;
> +        }
> +        nr_notifiers = nr_notifiers +
> +                       build_append_notification_callback(br_scope, sec);
> +        /*
> +         * add new child scope to parent
> +         * and keep track of bus that have PCNT,
> +         * bus list is used later to call children PCNTs from this level PCNT
> +         */
> +        if (nr_notifiers) {
> +            g_queue_push_tail(pcnt_bus_list, sec);
> +            aml_append(parent_scope, br_scope);
> +        }
> +    }
> +
> +    /*
> +     * Append PCNT method to notify about events on local and child buses.
> +     * ps: hostbridge might not have hotplug (bsel) enabled but might have
> +     * child bridges that do have bsel.
> +     */
> +    method = aml_method("PCNT", 0, AML_NOTSERIALIZED);
> +
> +    /* If bus supports hotplug select it and notify about local events */
> +    bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
> +    if (bsel) {
> +        uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
> +
> +        aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
> +        aml_append(method, aml_call2("DVNT", aml_name("PCIU"),
> +                                     aml_int(1))); /* Device Check */
> +        aml_append(method, aml_call2("DVNT", aml_name("PCID"),
> +                                     aml_int(3))); /* Eject Request */
> +        nr_notifiers++;
> +    }
> +
> +    /* Notify about child bus events in any case */
> +    while ((sec = g_queue_pop_head(pcnt_bus_list))) {
> +        aml_append(method, aml_name("^S%.02X.PCNT", sec->parent_dev->devfn));
> +    }
> +
> +    aml_append(parent_scope, method);
> +    qobject_unref(bsel);
> +    g_queue_free(pcnt_bus_list);
> +    return !!nr_notifiers;
> +}
> +
>   const VMStateDescription vmstate_acpi_pcihp_pci_status = {
>       .name = "acpi_pcihp_pci_status",
>       .version_id = 1,
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 87bb3d5cee..f08ce407c8 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -563,64 +563,6 @@ void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
>       }
>   }
>   
> -static bool build_append_notification_callback(Aml *parent_scope,
> -                                               const PCIBus *bus)
> -{
> -    Aml *method;
> -    PCIBus *sec;
> -    QObject *bsel;
> -    int nr_notifiers = 0;
> -    GQueue *pcnt_bus_list = g_queue_new();
> -
> -    QLIST_FOREACH(sec, &bus->child, sibling) {
> -        Aml *br_scope = aml_scope("S%.02X", sec->parent_dev->devfn);
> -        if (pci_bus_is_root(sec)) {
> -            continue;
> -        }
> -        nr_notifiers = nr_notifiers +
> -                       build_append_notification_callback(br_scope, sec);
> -        /*
> -         * add new child scope to parent
> -         * and keep track of bus that have PCNT,
> -         * bus list is used later to call children PCNTs from this level PCNT
> -         */
> -        if (nr_notifiers) {
> -            g_queue_push_tail(pcnt_bus_list, sec);
> -            aml_append(parent_scope, br_scope);
> -        }
> -    }
> -
> -    /*
> -     * Append PCNT method to notify about events on local and child buses.
> -     * ps: hostbridge might not have hotplug (bsel) enabled but might have
> -     * child bridges that do have bsel.
> -     */
> -    method = aml_method("PCNT", 0, AML_NOTSERIALIZED);
> -
> -    /* If bus supports hotplug select it and notify about local events */
> -    bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
> -    if (bsel) {
> -        uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
> -
> -        aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
> -        aml_append(method, aml_call2("DVNT", aml_name("PCIU"),
> -                                     aml_int(1))); /* Device Check */
> -        aml_append(method, aml_call2("DVNT", aml_name("PCID"),
> -                                     aml_int(3))); /* Eject Request */
> -        nr_notifiers++;
> -    }
> -
> -    /* Notify about child bus events in any case */
> -    while ((sec = g_queue_pop_head(pcnt_bus_list))) {
> -        aml_append(method, aml_name("^S%.02X.PCNT", sec->parent_dev->devfn));
> -    }
> -
> -    aml_append(parent_scope, method);
> -    qobject_unref(bsel);
> -    g_queue_free(pcnt_bus_list);
> -    return !!nr_notifiers;
> -}
> -
>   /*
>    * build_prt - Define interrupt routing rules
>    *



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 12/22] hw/i386/acpi-build: Move build_append_pci_bus_devices/pcihp_slots to pcihp
  2025-05-14 17:00 ` [PATCH 12/22] hw/i386/acpi-build: Move build_append_pci_bus_devices/pcihp_slots " Eric Auger
@ 2025-05-20 19:59   ` Gustavo Romero
  0 siblings, 0 replies; 47+ messages in thread
From: Gustavo Romero @ 2025-05-20 19:59 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:00, Eric Auger wrote:
> We intend to reuse build_append_pci_bus_devices and
> build_append_pcihp_slots on ARM. So Let's move them to

nit: lowercase                     ---^


> hw/acpi/pcihp.c as well as all static helpers they
> use.
> 
> No functional change intended.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>   include/hw/acpi/pci.h   |   1 -
>   include/hw/acpi/pcihp.h |   2 +
>   hw/acpi/pcihp.c         | 173 ++++++++++++++++++++++++++++++++++++++++
>   hw/i386/acpi-build.c    | 172 ---------------------------------------
>   4 files changed, 175 insertions(+), 173 deletions(-)

Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>


Cheers,
Gustavo

> diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h
> index ab0187a894..4dca22c0e2 100644
> --- a/include/hw/acpi/pci.h
> +++ b/include/hw/acpi/pci.h
> @@ -37,7 +37,6 @@ typedef struct AcpiMcfgInfo {
>   void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info,
>                   const char *oem_id, const char *oem_table_id);
>   
> -void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
>   void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope);
>   
>   void build_srat_generic_affinity_structures(GArray *table_data);
> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
> index 7c5d59243f..4d820b4baf 100644
> --- a/include/hw/acpi/pcihp.h
> +++ b/include/hw/acpi/pcihp.h
> @@ -80,6 +80,8 @@ void build_append_pcihp_resources(Aml *table,
>                                     uint64_t io_addr, uint64_t io_len);
>   bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus);
>   
> +void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
> +
>   /* Called on reset */
>   void acpi_pcihp_reset(AcpiPciHpState *s);
>   
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index 907a08ac7f..942669ea89 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -27,6 +27,7 @@
>   #include "qemu/osdep.h"
>   #include "hw/acpi/pcihp.h"
>   #include "hw/acpi/aml-build.h"
> +#include "hw/acpi/acpi_aml_interface.h"
>   #include "hw/pci-host/i440fx.h"
>   #include "hw/pci/pci.h"
>   #include "hw/pci/pci_bridge.h"
> @@ -763,6 +764,178 @@ bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus)
>       return !!nr_notifiers;
>   }
>   
> +static void build_append_pcihp_notify_entry(Aml *method, int slot)
> +{
> +    Aml *if_ctx;
> +    int32_t devfn = PCI_DEVFN(slot, 0);
> +
> +    if_ctx = aml_if(aml_and(aml_arg(0), aml_int(0x1U << slot), NULL));
> +    aml_append(if_ctx, aml_notify(aml_name("S%.02X", devfn), aml_arg(1)));
> +    aml_append(method, if_ctx);
> +}
> +
> +static bool is_devfn_ignored_generic(const int devfn, const PCIBus *bus)
> +{
> +    const PCIDevice *pdev = bus->devices[devfn];
> +
> +    if (PCI_FUNC(devfn)) {
> +        if (IS_PCI_BRIDGE(pdev)) {
> +            /*
> +             * Ignore only hotplugged PCI bridges on !0 functions, but
> +             * allow describing cold plugged bridges on all functions
> +             */
> +            if (DEVICE(pdev)->hotplugged) {
> +                return true;
> +            }
> +        }
> +    }
> +    return false;
> +}
> +
> +static bool is_devfn_ignored_hotplug(const int devfn, const PCIBus *bus)
> +{
> +    PCIDevice *pdev = bus->devices[devfn];
> +    if (pdev) {
> +        return is_devfn_ignored_generic(devfn, bus) ||
> +               !DEVICE_GET_CLASS(pdev)->hotpluggable ||
> +               /* Cold plugged bridges aren't themselves hot-pluggable */
> +               (IS_PCI_BRIDGE(pdev) && !DEVICE(pdev)->hotplugged);
> +    } else { /* non populated slots */
> +         /*
> +          * hotplug is supported only for non-multifunction device
> +          * so generate device description only for function 0
> +          */
> +        if (PCI_FUNC(devfn) ||
> +            (pci_bus_is_express(bus) && PCI_SLOT(devfn) > 0)) {
> +            return true;
> +        }
> +    }
> +    return false;
> +}
> +
> +static Aml *aml_pci_static_endpoint_dsm(PCIDevice *pdev)
> +{
> +    Aml *method;
> +
> +    g_assert(pdev->acpi_index != 0);
> +    method = aml_method("_DSM", 4, AML_SERIALIZED);
> +    {
> +        Aml *params = aml_local(0);
> +        Aml *pkg = aml_package(1);
> +        aml_append(pkg, aml_int(pdev->acpi_index));
> +        aml_append(method, aml_store(pkg, params));
> +        aml_append(method,
> +            aml_return(aml_call5("EDSM", aml_arg(0), aml_arg(1),
> +                                 aml_arg(2), aml_arg(3), params))
> +        );
> +    }
> +    return method;
> +}
> +
> +static Aml *aml_pci_device_dsm(void)
> +{
> +    Aml *method;
> +
> +    method = aml_method("_DSM", 4, AML_SERIALIZED);
> +    {
> +        Aml *params = aml_local(0);
> +        Aml *pkg = aml_package(2);
> +        aml_append(pkg, aml_int(0));
> +        aml_append(pkg, aml_int(0));
> +        aml_append(method, aml_store(pkg, params));
> +        aml_append(method,
> +            aml_store(aml_name("BSEL"), aml_index(params, aml_int(0))));
> +        aml_append(method,
> +            aml_store(aml_name("ASUN"), aml_index(params, aml_int(1))));
> +        aml_append(method,
> +            aml_return(aml_call5("PDSM", aml_arg(0), aml_arg(1),
> +                                 aml_arg(2), aml_arg(3), params))
> +        );
> +    }
> +    return method;
> +}
> +
> +void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus)
> +{
> +    int devfn;
> +    Aml *dev, *notify_method = NULL, *method;
> +    QObject *bsel = object_property_get_qobject(OBJECT(bus),
> +                        ACPI_PCIHP_PROP_BSEL, NULL);
> +    uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
> +    qobject_unref(bsel);
> +
> +    aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
> +    notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED);
> +
> +    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
> +        int slot = PCI_SLOT(devfn);
> +        int adr = slot << 16 | PCI_FUNC(devfn);
> +
> +        if (is_devfn_ignored_hotplug(devfn, bus)) {
> +            continue;
> +        }
> +
> +        if (bus->devices[devfn]) {
> +            dev = aml_scope("S%.02X", devfn);
> +        } else {
> +            dev = aml_device("S%.02X", devfn);
> +            aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
> +        }
> +
> +        /*
> +         * Can't declare _SUN here for every device as it changes 'slot'
> +         * enumeration order in linux kernel, so use another variable for it
> +         */
> +        aml_append(dev, aml_name_decl("ASUN", aml_int(slot)));
> +        aml_append(dev, aml_pci_device_dsm());
> +
> +        aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
> +        /* add _EJ0 to make slot hotpluggable  */
> +        method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
> +        aml_append(method,
> +            aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
> +        );
> +        aml_append(dev, method);
> +
> +        build_append_pcihp_notify_entry(notify_method, slot);
> +
> +        /* device descriptor has been composed, add it into parent context */
> +        aml_append(parent_scope, dev);
> +    }
> +    aml_append(parent_scope, notify_method);
> +}
> +
> +void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
> +{
> +    int devfn;
> +    Aml *dev;
> +
> +    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
> +        /* ACPI spec: 1.0b: Table 6-2 _ADR Object Bus Types, PCI type */
> +        int adr = PCI_SLOT(devfn) << 16 | PCI_FUNC(devfn);
> +        PCIDevice *pdev = bus->devices[devfn];
> +
> +        if (!pdev || is_devfn_ignored_generic(devfn, bus)) {
> +            continue;
> +        }
> +
> +        /* start to compose PCI device descriptor */
> +        dev = aml_device("S%.02X", devfn);
> +        aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
> +
> +        call_dev_aml_func(DEVICE(bus->devices[devfn]), dev);
> +        /* add _DSM if device has acpi-index set */
> +        if (pdev->acpi_index &&
> +            !object_property_get_bool(OBJECT(pdev), "hotpluggable",
> +                                      &error_abort)) {
> +            aml_append(dev, aml_pci_static_endpoint_dsm(pdev));
> +        }
> +
> +        /* device descriptor has been composed, add it into parent context */
> +        aml_append(parent_scope, dev);
> +    }
> +}
> +
>   const VMStateDescription vmstate_acpi_pcihp_pci_status = {
>       .name = "acpi_pcihp_pci_status",
>       .version_id = 1,
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index f08ce407c8..06b4b8eed4 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -338,29 +338,6 @@ build_facs(GArray *table_data)
>       g_array_append_vals(table_data, reserved, 40); /* Reserved */
>   }
>   
> -static Aml *aml_pci_device_dsm(void)
> -{
> -    Aml *method;
> -
> -    method = aml_method("_DSM", 4, AML_SERIALIZED);
> -    {
> -        Aml *params = aml_local(0);
> -        Aml *pkg = aml_package(2);
> -        aml_append(pkg, aml_int(0));
> -        aml_append(pkg, aml_int(0));
> -        aml_append(method, aml_store(pkg, params));
> -        aml_append(method,
> -            aml_store(aml_name("BSEL"), aml_index(params, aml_int(0))));
> -        aml_append(method,
> -            aml_store(aml_name("ASUN"), aml_index(params, aml_int(1))));
> -        aml_append(method,
> -            aml_return(aml_call5("PDSM", aml_arg(0), aml_arg(1),
> -                                 aml_arg(2), aml_arg(3), params))
> -        );
> -    }
> -    return method;
> -}
> -
>   static Aml *aml_pci_edsm(void)
>   {
>       Aml *method, *ifctx;
> @@ -414,155 +391,6 @@ static Aml *aml_pci_edsm(void)
>       return method;
>   }
>   
> -static Aml *aml_pci_static_endpoint_dsm(PCIDevice *pdev)
> -{
> -    Aml *method;
> -
> -    g_assert(pdev->acpi_index != 0);
> -    method = aml_method("_DSM", 4, AML_SERIALIZED);
> -    {
> -        Aml *params = aml_local(0);
> -        Aml *pkg = aml_package(1);
> -        aml_append(pkg, aml_int(pdev->acpi_index));
> -        aml_append(method, aml_store(pkg, params));
> -        aml_append(method,
> -            aml_return(aml_call5("EDSM", aml_arg(0), aml_arg(1),
> -                                 aml_arg(2), aml_arg(3), params))
> -        );
> -    }
> -    return method;
> -}
> -
> -static void build_append_pcihp_notify_entry(Aml *method, int slot)
> -{
> -    Aml *if_ctx;
> -    int32_t devfn = PCI_DEVFN(slot, 0);
> -
> -    if_ctx = aml_if(aml_and(aml_arg(0), aml_int(0x1U << slot), NULL));
> -    aml_append(if_ctx, aml_notify(aml_name("S%.02X", devfn), aml_arg(1)));
> -    aml_append(method, if_ctx);
> -}
> -
> -static bool is_devfn_ignored_generic(const int devfn, const PCIBus *bus)
> -{
> -    const PCIDevice *pdev = bus->devices[devfn];
> -
> -    if (PCI_FUNC(devfn)) {
> -        if (IS_PCI_BRIDGE(pdev)) {
> -            /*
> -             * Ignore only hotplugged PCI bridges on !0 functions, but
> -             * allow describing cold plugged bridges on all functions
> -             */
> -            if (DEVICE(pdev)->hotplugged) {
> -                return true;
> -            }
> -        }
> -    }
> -    return false;
> -}
> -
> -static bool is_devfn_ignored_hotplug(const int devfn, const PCIBus *bus)
> -{
> -    PCIDevice *pdev = bus->devices[devfn];
> -    if (pdev) {
> -        return is_devfn_ignored_generic(devfn, bus) ||
> -               !DEVICE_GET_CLASS(pdev)->hotpluggable ||
> -               /* Cold plugged bridges aren't themselves hot-pluggable */
> -               (IS_PCI_BRIDGE(pdev) && !DEVICE(pdev)->hotplugged);
> -    } else { /* non populated slots */
> -         /*
> -         * hotplug is supported only for non-multifunction device
> -         * so generate device description only for function 0
> -         */
> -        if (PCI_FUNC(devfn) ||
> -            (pci_bus_is_express(bus) && PCI_SLOT(devfn) > 0)) {
> -            return true;
> -        }
> -    }
> -    return false;
> -}
> -
> -void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus)
> -{
> -    int devfn;
> -    Aml *dev, *notify_method = NULL, *method;
> -    QObject *bsel = object_property_get_qobject(OBJECT(bus),
> -                        ACPI_PCIHP_PROP_BSEL, NULL);
> -    uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
> -    qobject_unref(bsel);
> -
> -    aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
> -    notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED);
> -
> -    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
> -        int slot = PCI_SLOT(devfn);
> -        int adr = slot << 16 | PCI_FUNC(devfn);
> -
> -        if (is_devfn_ignored_hotplug(devfn, bus)) {
> -            continue;
> -        }
> -
> -        if (bus->devices[devfn]) {
> -            dev = aml_scope("S%.02X", devfn);
> -        } else {
> -            dev = aml_device("S%.02X", devfn);
> -            aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
> -        }
> -
> -        /*
> -         * Can't declare _SUN here for every device as it changes 'slot'
> -         * enumeration order in linux kernel, so use another variable for it
> -         */
> -        aml_append(dev, aml_name_decl("ASUN", aml_int(slot)));
> -        aml_append(dev, aml_pci_device_dsm());
> -
> -        aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
> -        /* add _EJ0 to make slot hotpluggable  */
> -        method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
> -        aml_append(method,
> -            aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
> -        );
> -        aml_append(dev, method);
> -
> -        build_append_pcihp_notify_entry(notify_method, slot);
> -
> -        /* device descriptor has been composed, add it into parent context */
> -        aml_append(parent_scope, dev);
> -    }
> -    aml_append(parent_scope, notify_method);
> -}
> -
> -void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
> -{
> -    int devfn;
> -    Aml *dev;
> -
> -    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
> -        /* ACPI spec: 1.0b: Table 6-2 _ADR Object Bus Types, PCI type */
> -        int adr = PCI_SLOT(devfn) << 16 | PCI_FUNC(devfn);
> -        PCIDevice *pdev = bus->devices[devfn];
> -
> -        if (!pdev || is_devfn_ignored_generic(devfn, bus)) {
> -            continue;
> -        }
> -
> -        /* start to compose PCI device descriptor */
> -        dev = aml_device("S%.02X", devfn);
> -        aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
> -
> -        call_dev_aml_func(DEVICE(bus->devices[devfn]), dev);
> -        /* add _DSM if device has acpi-index set */
> -        if (pdev->acpi_index &&
> -            !object_property_get_bool(OBJECT(pdev), "hotpluggable",
> -                                      &error_abort)) {
> -            aml_append(dev, aml_pci_static_endpoint_dsm(pdev));
> -        }
> -
> -        /* device descriptor has been composed, add it into parent context */
> -        aml_append(parent_scope, dev);
> -    }
> -}
> -
>   /*
>    * build_prt - Define interrupt routing rules
>    *



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 13/22] hw/i386/acpi-build: Introduce and use acpi_get_pci_host
  2025-05-14 17:01 ` [PATCH 13/22] hw/i386/acpi-build: Introduce and use acpi_get_pci_host Eric Auger
@ 2025-05-20 20:00   ` Gustavo Romero
  2025-05-26  9:16     ` Eric Auger
  0 siblings, 1 reply; 47+ messages in thread
From: Gustavo Romero @ 2025-05-20 20:00 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:01, Eric Auger wrote:
> pcihp acpi_set_pci_info() generic code currently uses
> acpi_get_i386_pci_host() to retrieve the pci host bridge.
> 
> Let's rename acpi_get_i386_pci_host into acpi_get_pci_host and
> move it in pci generic code.
> 
> The helper is augmented with the support of ARM GPEX.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>   include/hw/acpi/pci.h |  2 ++
>   hw/acpi/pci.c         | 20 ++++++++++++++++++++
>   hw/acpi/pcihp.c       |  3 ++-
>   hw/i386/acpi-build.c  | 24 ++++--------------------
>   4 files changed, 28 insertions(+), 21 deletions(-)
> 
> diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h
> index 4dca22c0e2..310cbd02db 100644
> --- a/include/hw/acpi/pci.h
> +++ b/include/hw/acpi/pci.h
> @@ -41,4 +41,6 @@ void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope);
>   
>   void build_srat_generic_affinity_structures(GArray *table_data);
>   
> +Object *acpi_get_pci_host(void);
> +
>   #endif
> diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c
> index d511a85029..4191886ebe 100644
> --- a/hw/acpi/pci.c
> +++ b/hw/acpi/pci.c
> @@ -26,6 +26,7 @@
>   #include "qemu/osdep.h"
>   #include "qemu/error-report.h"
>   #include "qom/object_interfaces.h"
> +#include "qom/object.h"
>   #include "qapi/error.h"
>   #include "hw/boards.h"
>   #include "hw/acpi/aml-build.h"
> @@ -33,6 +34,9 @@
>   #include "hw/pci/pci_bridge.h"
>   #include "hw/pci/pci_device.h"
>   #include "hw/pci/pcie_host.h"
> +#include "hw/pci-host/i440fx.h"
> +#include "hw/pci-host/q35.h"
> +#include "hw/pci-host/gpex.h"
>   
>   /*
>    * PCI Firmware Specification, Revision 3.0
> @@ -301,3 +305,19 @@ void build_srat_generic_affinity_structures(GArray *table_data)
>       object_child_foreach_recursive(object_get_root(), build_acpi_generic_port,
>                                      table_data);
>   }
> +
> +Object *acpi_get_pci_host(void)
> +{
> +    Object *host;
> +
> +    host = object_resolve_type_unambiguous(TYPE_I440FX_PCI_HOST_BRIDGE, NULL);
> +    if (host) {
> +        return host;
> +    }
> +    host = object_resolve_type_unambiguous(TYPE_Q35_HOST_DEVICE, NULL);
> +    if (host) {
> +        return host;
> +    }
> +    host = object_resolve_type_unambiguous(TYPE_GPEX_HOST, NULL);
> +    return host;
> +}
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index 942669ea89..d800371ddc 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -36,6 +36,7 @@
>   #include "hw/pci-bridge/xio3130_downstream.h"
>   #include "hw/i386/acpi-build.h"
>   #include "hw/acpi/acpi.h"
> +#include "hw/acpi/pci.h"
>   #include "hw/pci/pci_bus.h"
>   #include "migration/vmstate.h"
>   #include "qapi/error.h"
> @@ -102,7 +103,7 @@ static void *acpi_set_bsel(PCIBus *bus, void *opaque)
>   static void acpi_set_pci_info(bool has_bridge_hotplug)
>   {
>       static bool bsel_is_set;
> -    Object *host = acpi_get_i386_pci_host();
> +    Object *host = acpi_get_pci_host();
>       PCIBus *bus;
>       BSELInfo info = { .bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT,
>                         .has_bridge_hotplug = has_bridge_hotplug };
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 06b4b8eed4..bcfba2ccb3 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -269,27 +269,11 @@ static void acpi_get_misc_info(AcpiMiscInfo *info)
>   #endif
>   }
>   
> -/*
> - * Because of the PXB hosts we cannot simply query TYPE_PCI_HOST_BRIDGE.
> - * On i386 arch we only have two pci hosts, so we can look only for them.
> - */
> -Object *acpi_get_i386_pci_host(void)
> -{
> -    PCIHostState *host;
> -
> -    host = PCI_HOST_BRIDGE(object_resolve_path("/machine/i440fx", NULL));
> -    if (!host) {
> -        host = PCI_HOST_BRIDGE(object_resolve_path("/machine/q35", NULL));
> -    }
> -
> -    return OBJECT(host);
> -}
> -

It's also possible to add a child prop to the TYPE_GPEX_HOST in create_pcie, like:

@@ -1510,6 +1510,7 @@ static void create_pcie(VirtMachineState *vms)
      MachineClass *mc = MACHINE_GET_CLASS(ms);
  
      dev = qdev_new(TYPE_GPEX_HOST);
+    object_property_add_child(OBJECT(vms), "gpex", OBJECT(dev));

then follow to logic in acpi_get_i386_pci_host via:

PCI_HOST_BRIDGE(object_resolve_path("/machine/gpex", NULL))

but I like better your solution of using the final class types, so:

Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>


Cheers,
Gustavo

>   static void acpi_get_pci_holes(Range *hole, Range *hole64)
>   {
>       Object *pci_host;
>   
> -    pci_host = acpi_get_i386_pci_host();
> +    pci_host = acpi_get_pci_host();
>   
>       if (!pci_host) {
>           return;
> @@ -1245,7 +1229,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>   
>       sb_scope = aml_scope("\\_SB");
>       {
> -        Object *pci_host = acpi_get_i386_pci_host();
> +        Object *pci_host = acpi_get_pci_host();
>   
>           if (pci_host) {
>               PCIBus *pbus = PCI_HOST_BRIDGE(pci_host)->bus;
> @@ -1306,7 +1290,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>       if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
>           bool has_pcnt;
>   
> -        Object *pci_host = acpi_get_i386_pci_host();
> +        Object *pci_host = acpi_get_pci_host();
>           PCIBus *b = PCI_HOST_BRIDGE(pci_host)->bus;
>   
>           scope = aml_scope("\\_SB.PCI0");
> @@ -1946,7 +1930,7 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
>       Object *pci_host;
>       QObject *o;
>   
> -    pci_host = acpi_get_i386_pci_host();
> +    pci_host = acpi_get_pci_host();
>       if (!pci_host) {
>           return false;
>       }



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place
  2025-05-14 17:01 ` [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place Eric Auger
@ 2025-05-21 15:26   ` Gustavo Romero
  2025-05-21 15:56     ` Eric Auger
  0 siblings, 1 reply; 47+ messages in thread
From: Gustavo Romero @ 2025-05-21 15:26 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:01, Eric Auger wrote:
> Move aml_pci_edsm to pcihp since we want to reuse that for
> ARM and acpi-index support.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>   include/hw/acpi/pcihp.h |  2 ++
>   hw/acpi/pcihp.c         | 53 +++++++++++++++++++++++++++++++++++++++++
>   hw/i386/acpi-build.c    | 53 -----------------------------------------
>   3 files changed, 55 insertions(+), 53 deletions(-)
> 
> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
> index 4d820b4baf..bc31dbff39 100644
> --- a/include/hw/acpi/pcihp.h
> +++ b/include/hw/acpi/pcihp.h
> @@ -82,6 +82,8 @@ bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus);
>   
>   void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
>   
> +Aml *aml_pci_edsm(void);
> +
>   /* Called on reset */
>   void acpi_pcihp_reset(AcpiPciHpState *s);
>   
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index d800371ddc..57fe8938b1 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -937,6 +937,59 @@ void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
>       }
>   }
>   
> +Aml *aml_pci_edsm(void)
> +{
> +    Aml *method, *ifctx;
> +    Aml *zero = aml_int(0);
> +    Aml *func = aml_arg(2);
> +    Aml *ret = aml_local(0);
> +    Aml *aidx = aml_local(1);
> +    Aml *params = aml_arg(4);
> +
> +    method = aml_method("EDSM", 5, AML_SERIALIZED);
> +
> +    /* get supported functions */
> +    ifctx = aml_if(aml_equal(func, zero));
> +    {
> +        /* 1: have supported functions */
> +        /* 7: support for function 7 */
> +        const uint8_t caps = 1 | BIT(7);
> +        build_append_pci_dsm_func0_common(ifctx, ret);
> +        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret, zero)));
> +        aml_append(ifctx, aml_return(ret));
> +    }
> +    aml_append(method, ifctx);
> +
> +    /* handle specific functions requests */
> +    /*
> +     * PCI Firmware Specification 3.1
> +     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
> +     *        Operating Systems
> +     */
> +    ifctx = aml_if(aml_equal(func, aml_int(7)));
> +    {
> +       Aml *pkg = aml_package(2);
> +       aml_append(pkg, zero);
> +       /* optional, if not impl. should return null string */
> +       aml_append(pkg, aml_string("%s", ""));
> +       aml_append(ifctx, aml_store(pkg, ret));
> +
> +       /*
> +        * IASL is fine when initializing Package with computational data,
> +        * however it makes guest unhappy /it fails to process such AML/.
> +        * So use runtime assignment to set acpi-index after initializer
> +        * to make OSPM happy.
> +        */
> +       aml_append(ifctx,
> +           aml_store(aml_derefof(aml_index(params, aml_int(0))), aidx));
> +       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
> +       aml_append(ifctx, aml_return(ret));
> +    }
> +    aml_append(method, ifctx);
> +
> +    return method;
> +}
> +
>   const VMStateDescription vmstate_acpi_pcihp_pci_status = {
>       .name = "acpi_pcihp_pci_status",
>       .version_id = 1,
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index bcfba2ccb3..385e75d061 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -322,59 +322,6 @@ build_facs(GArray *table_data)
>       g_array_append_vals(table_data, reserved, 40); /* Reserved */
>   }
>   
> -static Aml *aml_pci_edsm(void)
> -{
> -    Aml *method, *ifctx;
> -    Aml *zero = aml_int(0);
> -    Aml *func = aml_arg(2);
> -    Aml *ret = aml_local(0);
> -    Aml *aidx = aml_local(1);
> -    Aml *params = aml_arg(4);
> -
> -    method = aml_method("EDSM", 5, AML_SERIALIZED);
> -
> -    /* get supported functions */
> -    ifctx = aml_if(aml_equal(func, zero));
> -    {
> -        /* 1: have supported functions */
> -        /* 7: support for function 7 */
> -        const uint8_t caps = 1 | BIT(7);
> -        build_append_pci_dsm_func0_common(ifctx, ret);
> -        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret, zero)));
> -        aml_append(ifctx, aml_return(ret));
> -    }
> -    aml_append(method, ifctx);
> -
> -    /* handle specific functions requests */
> -    /*
> -     * PCI Firmware Specification 3.1
> -     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
> -     *        Operating Systems
> -     */
> -    ifctx = aml_if(aml_equal(func, aml_int(7)));
> -    {
> -       Aml *pkg = aml_package(2);
> -       aml_append(pkg, zero);
> -       /* optional, if not impl. should return null string */
> -       aml_append(pkg, aml_string("%s", ""));
> -       aml_append(ifctx, aml_store(pkg, ret));
> -
> -       /*
> -        * IASL is fine when initializing Package with computational data,
> -        * however it makes guest unhappy /it fails to process such AML/.
> -        * So use runtime assignment to set acpi-index after initializer
> -        * to make OSPM happy.
> -        */
> -       aml_append(ifctx,
> -           aml_store(aml_derefof(aml_index(params, aml_int(0))), aidx));
> -       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
> -       aml_append(ifctx, aml_return(ret));
> -    }
> -    aml_append(method, ifctx);
> -
> -    return method;
> -}
> -
>   /*
>    * build_prt - Define interrupt routing rules
>    *

EDSM is not called from anywhere. _DSM method actually calls the PDSM, already defined
in pcihp.c and generated by aml_pci_pdsm(). build_acpi_pci_hotplug(), which calls
aml_pci_pdsm(), properly creates the PDSM method. Then in build_append_pcihp_slots()
the a _DSM is defined per slot and inside it there is a call to PDSM, so I understand
we should actually stick to the PDSM in pcihp.c instead of EDSM.

EDSM, being used in i386 code, feels a outdated PDSM, so maybe PDSM should be used there,
although a different story or a clean up for later. I'm not sure what "static endpoint"
means in the context of EDSM.

Hence this patch can be dropped in my understanding and:

aml_append(pci0_scope, aml_pci_edsm()) in 15/22 too, without any prejudice to the
hotplugging and unplugging in this series.


Cheers,
Gustavo


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place
  2025-05-21 15:26   ` Gustavo Romero
@ 2025-05-21 15:56     ` Eric Auger
  2025-05-21 16:24       ` Gustavo Romero
  0 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-21 15:56 UTC (permalink / raw)
  To: Gustavo Romero, eric.auger.pro, qemu-devel, qemu-arm,
	peter.maydell, imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Gustavo,

On 5/21/25 5:26 PM, Gustavo Romero wrote:
> Hi Eric,
>
> On 5/14/25 14:01, Eric Auger wrote:
>> Move aml_pci_edsm to pcihp since we want to reuse that for
>> ARM and acpi-index support.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> ---
>>   include/hw/acpi/pcihp.h |  2 ++
>>   hw/acpi/pcihp.c         | 53 +++++++++++++++++++++++++++++++++++++++++
>>   hw/i386/acpi-build.c    | 53 -----------------------------------------
>>   3 files changed, 55 insertions(+), 53 deletions(-)
>>
>> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
>> index 4d820b4baf..bc31dbff39 100644
>> --- a/include/hw/acpi/pcihp.h
>> +++ b/include/hw/acpi/pcihp.h
>> @@ -82,6 +82,8 @@ bool build_append_notification_callback(Aml
>> *parent_scope, const PCIBus *bus);
>>     void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
>>   +Aml *aml_pci_edsm(void);
>> +
>>   /* Called on reset */
>>   void acpi_pcihp_reset(AcpiPciHpState *s);
>>   diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
>> index d800371ddc..57fe8938b1 100644
>> --- a/hw/acpi/pcihp.c
>> +++ b/hw/acpi/pcihp.c
>> @@ -937,6 +937,59 @@ void build_append_pci_bus_devices(Aml
>> *parent_scope, PCIBus *bus)
>>       }
>>   }
>>   +Aml *aml_pci_edsm(void)
>> +{
>> +    Aml *method, *ifctx;
>> +    Aml *zero = aml_int(0);
>> +    Aml *func = aml_arg(2);
>> +    Aml *ret = aml_local(0);
>> +    Aml *aidx = aml_local(1);
>> +    Aml *params = aml_arg(4);
>> +
>> +    method = aml_method("EDSM", 5, AML_SERIALIZED);
>> +
>> +    /* get supported functions */
>> +    ifctx = aml_if(aml_equal(func, zero));
>> +    {
>> +        /* 1: have supported functions */
>> +        /* 7: support for function 7 */
>> +        const uint8_t caps = 1 | BIT(7);
>> +        build_append_pci_dsm_func0_common(ifctx, ret);
>> +        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret,
>> zero)));
>> +        aml_append(ifctx, aml_return(ret));
>> +    }
>> +    aml_append(method, ifctx);
>> +
>> +    /* handle specific functions requests */
>> +    /*
>> +     * PCI Firmware Specification 3.1
>> +     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
>> +     *        Operating Systems
>> +     */
>> +    ifctx = aml_if(aml_equal(func, aml_int(7)));
>> +    {
>> +       Aml *pkg = aml_package(2);
>> +       aml_append(pkg, zero);
>> +       /* optional, if not impl. should return null string */
>> +       aml_append(pkg, aml_string("%s", ""));
>> +       aml_append(ifctx, aml_store(pkg, ret));
>> +
>> +       /*
>> +        * IASL is fine when initializing Package with computational
>> data,
>> +        * however it makes guest unhappy /it fails to process such
>> AML/.
>> +        * So use runtime assignment to set acpi-index after initializer
>> +        * to make OSPM happy.
>> +        */
>> +       aml_append(ifctx,
>> +           aml_store(aml_derefof(aml_index(params, aml_int(0))),
>> aidx));
>> +       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
>> +       aml_append(ifctx, aml_return(ret));
>> +    }
>> +    aml_append(method, ifctx);
>> +
>> +    return method;
>> +}
>> +
>>   const VMStateDescription vmstate_acpi_pcihp_pci_status = {
>>       .name = "acpi_pcihp_pci_status",
>>       .version_id = 1,
>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>> index bcfba2ccb3..385e75d061 100644
>> --- a/hw/i386/acpi-build.c
>> +++ b/hw/i386/acpi-build.c
>> @@ -322,59 +322,6 @@ build_facs(GArray *table_data)
>>       g_array_append_vals(table_data, reserved, 40); /* Reserved */
>>   }
>>   -static Aml *aml_pci_edsm(void)
>> -{
>> -    Aml *method, *ifctx;
>> -    Aml *zero = aml_int(0);
>> -    Aml *func = aml_arg(2);
>> -    Aml *ret = aml_local(0);
>> -    Aml *aidx = aml_local(1);
>> -    Aml *params = aml_arg(4);
>> -
>> -    method = aml_method("EDSM", 5, AML_SERIALIZED);
>> -
>> -    /* get supported functions */
>> -    ifctx = aml_if(aml_equal(func, zero));
>> -    {
>> -        /* 1: have supported functions */
>> -        /* 7: support for function 7 */
>> -        const uint8_t caps = 1 | BIT(7);
>> -        build_append_pci_dsm_func0_common(ifctx, ret);
>> -        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret,
>> zero)));
>> -        aml_append(ifctx, aml_return(ret));
>> -    }
>> -    aml_append(method, ifctx);
>> -
>> -    /* handle specific functions requests */
>> -    /*
>> -     * PCI Firmware Specification 3.1
>> -     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
>> -     *        Operating Systems
>> -     */
>> -    ifctx = aml_if(aml_equal(func, aml_int(7)));
>> -    {
>> -       Aml *pkg = aml_package(2);
>> -       aml_append(pkg, zero);
>> -       /* optional, if not impl. should return null string */
>> -       aml_append(pkg, aml_string("%s", ""));
>> -       aml_append(ifctx, aml_store(pkg, ret));
>> -
>> -       /*
>> -        * IASL is fine when initializing Package with computational
>> data,
>> -        * however it makes guest unhappy /it fails to process such
>> AML/.
>> -        * So use runtime assignment to set acpi-index after initializer
>> -        * to make OSPM happy.
>> -        */
>> -       aml_append(ifctx,
>> -           aml_store(aml_derefof(aml_index(params, aml_int(0))),
>> aidx));
>> -       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
>> -       aml_append(ifctx, aml_return(ret));
>> -    }
>> -    aml_append(method, ifctx);
>> -
>> -    return method;
>> -}
>> -
>>   /*
>>    * build_prt - Define interrupt routing rules
>>    *
>
> EDSM is not called from anywhere. _DSM method actually calls the PDSM,
> already defined
> in pcihp.c and generated by aml_pci_pdsm(). build_acpi_pci_hotplug(),
> which calls
> aml_pci_pdsm(), properly creates the PDSM method. Then in
> build_append_pcihp_slots()
> the a _DSM is defined per slot and inside it there is a call to PDSM,
> so I understand
> we should actually stick to the PDSM in pcihp.c instead of EDSM.

I see build_append_pci_bus_devices -> aml_pci_static_endpoint_dsm
adds a _DSM method which eventually calls EDSM.

aml_pci_device_dsm builds another _DSM implementation which calls PDSM.

As we use build_append_pci_bus_devices and we are likely to have a _DSM
implementation that calls EDSM method, I think we shall have it in the
aml. What do I miss?

Thank you for the comprehensive review!

Cheers

Eric
>
> EDSM, being used in i386 code, feels a outdated PDSM, so maybe PDSM
> should be used there,
> although a different story or a clean up for later. I'm not sure what
> "static endpoint"
> means in the context of EDSM.
>
> Hence this patch can be dropped in my understanding and:
>
> aml_append(pci0_scope, aml_pci_edsm()) in 15/22 too, without any
> prejudice to the
> hotplugging and unplugging in this series.
>
>
> Cheers,
> Gustavo
>



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 08/22] hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method
  2025-05-20 14:09   ` Gustavo Romero
@ 2025-05-21 16:12     ` Eric Auger
  2025-05-24 10:54       ` Michael S. Tsirkin
  0 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-21 16:12 UTC (permalink / raw)
  To: Gustavo Romero, eric.auger.pro, qemu-devel, qemu-arm,
	peter.maydell, imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Gustavo,

On 5/20/25 4:09 PM, Gustavo Romero wrote:
> Hi Eric,
>
> On 5/14/25 14:00, Eric Auger wrote:
>> gpex build_host_bridge_osc() and x86 originated
>> build_pci_host_bridge_osc_method() are mostly identical.
>>
>> In GPEX, SUPP is set to CDW2 but is not further used. CTRL
>> is same as Local0.
>>
>> So let gpex code reuse build_pci_host_bridge_osc_method()
>> and remove build_host_bridge_osc().
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>
>> ---
>>
>> The DSDT diff  is given below:
>> diff --git a/dsdt.dsl_before b/dsdt.dsl_after_osc_change
>> index 3224a56..fa7558e 100644
>> --- a/dsdt.dsl_before
>> +++ b/dsdt.dsl_after_osc_change
>> @@ -5,13 +5,13 @@
>>    *
>>    * Disassembling to symbolic ASL+ operators
>>    *
>> - * Disassembly of dsdt.dat, Mon Apr  7 05:33:06 2025
>> + * Disassembly of dsdt.dat, Mon Apr  7 05:37:20 2025
>>    *
>>    * Original Table Header:
>>    *     Signature        "DSDT"
>> - *     Length           0x00001A4F (6735)
>> + *     Length           0x00001A35 (6709)
>>    *     Revision         0x02
>> - *     Checksum         0xBF
>> + *     Checksum         0xDD
>>    *     OEM ID           "BOCHS "
>>    *     OEM Table ID     "BXPC    "
>>    *     OEM Revision     0x00000001 (1)
>> @@ -1849,27 +1849,26 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ",
>> "BXPC    ", 0x00000001)
>>                   {
>>                       CreateDWordField (Arg3, 0x04, CDW2)
>>                       CreateDWordField (Arg3, 0x08, CDW3)
>> -                    SUPP = CDW2 /* \_SB_.PCI0._OSC.CDW2 */
>> -                    CTRL = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
>> -                    CTRL &= 0x1F
>> +                    Local0 = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
>> +                    Local0 &= 0x1F
>>                       If ((Arg1 != One))
>>                       {
>>                           CDW1 |= 0x08
>>                       }
>>
>> -                    If ((CDW3 != CTRL))
>> +                    If ((CDW3 != Local0))
>>                       {
>>                           CDW1 |= 0x10
>>                       }
>>
>> -                    CDW3 = CTRL /* \_SB_.PCI0.CTRL */
>> -                    Return (Arg3)
>> +                    CDW3 = Local0
>>                   }
>>                   Else
>>                   {
>>                       CDW1 |= 0x04
>> -                    Return (Arg3)
>>                   }
>> +
>> +                Return (Arg3)
>>               }
>>
>>               Method (_DSM, 4, NotSerialized)  // _DSM:
>> Device-Specific Method
>
> The problem I face with diffs in the commit body is that tools like
> b4, which are
> based on git am, get very confused on how to handle it. I'm surprised
> nobody ever
> complained about it. I'm wondering if there is any catch on it,
> because I have to
> edit commits like this manually, removing the diff, to make it finally
> apply to
> the series. Anyways, do you mind at least removing the valid diff
> header, like:
>
>> diff --git a/dsdt.dsl_before b/dsdt.dsl_after_osc_change
>> index 3224a56..fa7558e 100644
>> --- a/dsdt.dsl_before
>> +++ b/dsdt.dsl_after_osc_change
>
> from the commit message so it doesn't confuse b4?
Thank you for reporting the issue. in tests/qtest/bios-tables-test.c it
is written at the top that we shall put the diffs in disasembled ACPI
content in the commit msg. I will look for previously landed patches and
see whether the current layout can be fixed.

Cheers

Eric
>
>
>> ---
>>   hw/pci-host/gpex-acpi.c | 60 +++--------------------------------------
>>   1 file changed, 4 insertions(+), 56 deletions(-)
>>
>> diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
>> index f1ab30f3d5..98c9868c3f 100644
>> --- a/hw/pci-host/gpex-acpi.c
>> +++ b/hw/pci-host/gpex-acpi.c
>> @@ -50,60 +50,7 @@ static void acpi_dsdt_add_pci_route_table(Aml
>> *dev, uint32_t irq,
>>       }
>>   }
>>   -static Aml *build_host_bridge_osc(bool enable_native_pcie_hotplug)
>> -{
>> -    Aml *method, *UUID, *ifctx, *ifctx1, *elsectx;
>> -
>> -    method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
>> -    aml_append(method,
>> -        aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
>> -
>> -    /* PCI Firmware Specification 3.0
>> -     * 4.5.1. _OSC Interface for PCI Host Bridge Devices
>> -     * The _OSC interface for a PCI/PCI-X/PCI Express hierarchy is
>> -     * identified by the Universal Unique IDentifier (UUID)
>> -     * 33DB4D5B-1FF7-401C-9657-7441C03DD766
>> -     */
>> -    UUID = aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766");
>> -    ifctx = aml_if(aml_equal(aml_arg(0), UUID));
>> -    aml_append(ifctx,
>> -        aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
>> -    aml_append(ifctx,
>> -        aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
>> -    aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
>> -    aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
>> -
>> -    /*
>> -     * Allow OS control for SHPCHotplug, PME, AER, PCIeCapability,
>> -     * and PCIeHotplug depending on enable_native_pcie_hotplug
>> -     */
>> -    aml_append(ifctx, aml_and(aml_name("CTRL"),
>> -               aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 :
>> 0x0)),
>> -               aml_name("CTRL")));
>> -
>> -    ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
>> -    aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
>> -                              aml_name("CDW1")));
>> -    aml_append(ifctx, ifctx1);
>> -
>> -    ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"),
>> aml_name("CTRL"))));
>> -    aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10),
>> -                              aml_name("CDW1")));
>> -    aml_append(ifctx, ifctx1);
>> -
>> -    aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
>> -    aml_append(ifctx, aml_return(aml_arg(3)));
>> -    aml_append(method, ifctx);
>> -
>> -    elsectx = aml_else();
>> -    aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4),
>> -                               aml_name("CDW1")));
>> -    aml_append(elsectx, aml_return(aml_arg(3)));
>> -    aml_append(method, elsectx);
>> -    return method;
>> -}
>> -
>> -static Aml *build_host_bridge_dsm(void)
>> +static Aml *build_pci_host_bridge_dsm_method(void)
>>   {
>>       Aml *method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
>>       Aml *UUID, *ifctx, *ifctx1, *buf;
>> @@ -134,8 +81,9 @@ static void acpi_dsdt_add_host_bridge_methods(Aml
>> *dev,
>>       aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
>>       aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
>>       /* Declare an _OSC (OS Control Handoff) method */
>> -    aml_append(dev, build_host_bridge_osc(enable_native_pcie_hotplug));
>> -    aml_append(dev, build_host_bridge_dsm());
>> +    aml_append(dev,
>> +              
>> build_pci_host_bridge_osc_method(enable_native_pcie_hotplug));
>> +    aml_append(dev, build_pci_host_bridge_dsm_method());
>>   }
>>     void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
>
> Otherwise:
>
> Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>
>
>
> Cheers,
> Gustavo
>



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place
  2025-05-21 15:56     ` Eric Auger
@ 2025-05-21 16:24       ` Gustavo Romero
  2025-05-21 20:19         ` Gustavo Romero
  0 siblings, 1 reply; 47+ messages in thread
From: Gustavo Romero @ 2025-05-21 16:24 UTC (permalink / raw)
  To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/21/25 12:56, Eric Auger wrote:
> Hi Gustavo,
> 
> On 5/21/25 5:26 PM, Gustavo Romero wrote:
>> Hi Eric,
>>
>> On 5/14/25 14:01, Eric Auger wrote:
>>> Move aml_pci_edsm to pcihp since we want to reuse that for
>>> ARM and acpi-index support.
>>>
>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>> ---
>>>    include/hw/acpi/pcihp.h |  2 ++
>>>    hw/acpi/pcihp.c         | 53 +++++++++++++++++++++++++++++++++++++++++
>>>    hw/i386/acpi-build.c    | 53 -----------------------------------------
>>>    3 files changed, 55 insertions(+), 53 deletions(-)
>>>
>>> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
>>> index 4d820b4baf..bc31dbff39 100644
>>> --- a/include/hw/acpi/pcihp.h
>>> +++ b/include/hw/acpi/pcihp.h
>>> @@ -82,6 +82,8 @@ bool build_append_notification_callback(Aml
>>> *parent_scope, const PCIBus *bus);
>>>      void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
>>>    +Aml *aml_pci_edsm(void);
>>> +
>>>    /* Called on reset */
>>>    void acpi_pcihp_reset(AcpiPciHpState *s);
>>>    diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
>>> index d800371ddc..57fe8938b1 100644
>>> --- a/hw/acpi/pcihp.c
>>> +++ b/hw/acpi/pcihp.c
>>> @@ -937,6 +937,59 @@ void build_append_pci_bus_devices(Aml
>>> *parent_scope, PCIBus *bus)
>>>        }
>>>    }
>>>    +Aml *aml_pci_edsm(void)
>>> +{
>>> +    Aml *method, *ifctx;
>>> +    Aml *zero = aml_int(0);
>>> +    Aml *func = aml_arg(2);
>>> +    Aml *ret = aml_local(0);
>>> +    Aml *aidx = aml_local(1);
>>> +    Aml *params = aml_arg(4);
>>> +
>>> +    method = aml_method("EDSM", 5, AML_SERIALIZED);
>>> +
>>> +    /* get supported functions */
>>> +    ifctx = aml_if(aml_equal(func, zero));
>>> +    {
>>> +        /* 1: have supported functions */
>>> +        /* 7: support for function 7 */
>>> +        const uint8_t caps = 1 | BIT(7);
>>> +        build_append_pci_dsm_func0_common(ifctx, ret);
>>> +        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret,
>>> zero)));
>>> +        aml_append(ifctx, aml_return(ret));
>>> +    }
>>> +    aml_append(method, ifctx);
>>> +
>>> +    /* handle specific functions requests */
>>> +    /*
>>> +     * PCI Firmware Specification 3.1
>>> +     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
>>> +     *        Operating Systems
>>> +     */
>>> +    ifctx = aml_if(aml_equal(func, aml_int(7)));
>>> +    {
>>> +       Aml *pkg = aml_package(2);
>>> +       aml_append(pkg, zero);
>>> +       /* optional, if not impl. should return null string */
>>> +       aml_append(pkg, aml_string("%s", ""));
>>> +       aml_append(ifctx, aml_store(pkg, ret));
>>> +
>>> +       /*
>>> +        * IASL is fine when initializing Package with computational
>>> data,
>>> +        * however it makes guest unhappy /it fails to process such
>>> AML/.
>>> +        * So use runtime assignment to set acpi-index after initializer
>>> +        * to make OSPM happy.
>>> +        */
>>> +       aml_append(ifctx,
>>> +           aml_store(aml_derefof(aml_index(params, aml_int(0))),
>>> aidx));
>>> +       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
>>> +       aml_append(ifctx, aml_return(ret));
>>> +    }
>>> +    aml_append(method, ifctx);
>>> +
>>> +    return method;
>>> +}
>>> +
>>>    const VMStateDescription vmstate_acpi_pcihp_pci_status = {
>>>        .name = "acpi_pcihp_pci_status",
>>>        .version_id = 1,
>>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>>> index bcfba2ccb3..385e75d061 100644
>>> --- a/hw/i386/acpi-build.c
>>> +++ b/hw/i386/acpi-build.c
>>> @@ -322,59 +322,6 @@ build_facs(GArray *table_data)
>>>        g_array_append_vals(table_data, reserved, 40); /* Reserved */
>>>    }
>>>    -static Aml *aml_pci_edsm(void)
>>> -{
>>> -    Aml *method, *ifctx;
>>> -    Aml *zero = aml_int(0);
>>> -    Aml *func = aml_arg(2);
>>> -    Aml *ret = aml_local(0);
>>> -    Aml *aidx = aml_local(1);
>>> -    Aml *params = aml_arg(4);
>>> -
>>> -    method = aml_method("EDSM", 5, AML_SERIALIZED);
>>> -
>>> -    /* get supported functions */
>>> -    ifctx = aml_if(aml_equal(func, zero));
>>> -    {
>>> -        /* 1: have supported functions */
>>> -        /* 7: support for function 7 */
>>> -        const uint8_t caps = 1 | BIT(7);
>>> -        build_append_pci_dsm_func0_common(ifctx, ret);
>>> -        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret,
>>> zero)));
>>> -        aml_append(ifctx, aml_return(ret));
>>> -    }
>>> -    aml_append(method, ifctx);
>>> -
>>> -    /* handle specific functions requests */
>>> -    /*
>>> -     * PCI Firmware Specification 3.1
>>> -     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
>>> -     *        Operating Systems
>>> -     */
>>> -    ifctx = aml_if(aml_equal(func, aml_int(7)));
>>> -    {
>>> -       Aml *pkg = aml_package(2);
>>> -       aml_append(pkg, zero);
>>> -       /* optional, if not impl. should return null string */
>>> -       aml_append(pkg, aml_string("%s", ""));
>>> -       aml_append(ifctx, aml_store(pkg, ret));
>>> -
>>> -       /*
>>> -        * IASL is fine when initializing Package with computational
>>> data,
>>> -        * however it makes guest unhappy /it fails to process such
>>> AML/.
>>> -        * So use runtime assignment to set acpi-index after initializer
>>> -        * to make OSPM happy.
>>> -        */
>>> -       aml_append(ifctx,
>>> -           aml_store(aml_derefof(aml_index(params, aml_int(0))),
>>> aidx));
>>> -       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
>>> -       aml_append(ifctx, aml_return(ret));
>>> -    }
>>> -    aml_append(method, ifctx);
>>> -
>>> -    return method;
>>> -}
>>> -
>>>    /*
>>>     * build_prt - Define interrupt routing rules
>>>     *
>>
>> EDSM is not called from anywhere. _DSM method actually calls the PDSM,
>> already defined
>> in pcihp.c and generated by aml_pci_pdsm(). build_acpi_pci_hotplug(),
>> which calls
>> aml_pci_pdsm(), properly creates the PDSM method. Then in
>> build_append_pcihp_slots()
>> the a _DSM is defined per slot and inside it there is a call to PDSM,
>> so I understand
>> we should actually stick to the PDSM in pcihp.c instead of EDSM.
> 
> I see build_append_pci_bus_devices -> aml_pci_static_endpoint_dsm
> adds a _DSM method which eventually calls EDSM.

Yes, but I meant in the final generated ACPI AML code.


> aml_pci_device_dsm builds another _DSM implementation which calls PDSM.
> 
> As we use build_append_pci_bus_devices and we are likely to have a _DSM
> implementation that calls EDSM method, I think we shall have it in the
> aml. What do I miss?

Maybe some condition in build_append_pci_bus_devices() of:

         if (pdev->acpi_index &&
             !object_property_get_bool(OBJECT(pdev), "hotpluggable",
                                       &error_abort)) { ... }


is not met?

Does your _DSM method in the machine's ACPI has a call to EDSM? I don't
see it. In my case it's the PDSM that is being called:

gromero@xps13:/tmp$ grep -n PDSM dsdt.dsl
1910:        Method (PDSM, 5, Serialized)
2047:                    Return (PDSM (Arg0, Arg1, Arg2, Arg3, Local0))
gromero@xps13:/tmp$ grep -n EDSM dsdt.dsl
1959:        Method (EDSM, 5, Serialized)
gromero@xps13:/tmp$

I also confirmed that PDSM is what is being used by reverting this patch and
dropping the aml_append(pci0_scope, aml_pci_edsm()); in 15/22.

But also, why shouldn't we use the PDSM defined already in pcihp.c? This is
indeed crafted for the acpi-pcihp-hotplug device as I understand it.


Cheers,
Gustavo

> Thank you for the comprehensive review!
> 
> Cheers
> 
> Eric
>>
>> EDSM, being used in i386 code, feels a outdated PDSM, so maybe PDSM
>> should be used there,
>> although a different story or a clean up for later. I'm not sure what
>> "static endpoint"
>> means in the context of EDSM.
>>
>> Hence this patch can be dropped in my understanding and:
>>
>> aml_append(pci0_scope, aml_pci_edsm()) in 15/22 too, without any
>> prejudice to the
>> hotplugging and unplugging in this series.
>>
>>
>> Cheers,
>> Gustavo
>>
> 



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place
  2025-05-21 16:24       ` Gustavo Romero
@ 2025-05-21 20:19         ` Gustavo Romero
  2025-05-27  7:18           ` Eric Auger
  0 siblings, 1 reply; 47+ messages in thread
From: Gustavo Romero @ 2025-05-21 20:19 UTC (permalink / raw)
  To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/21/25 13:24, Gustavo Romero wrote:
> Hi Eric,
> 
> On 5/21/25 12:56, Eric Auger wrote:
>> Hi Gustavo,
>>
>> On 5/21/25 5:26 PM, Gustavo Romero wrote:
>>> Hi Eric,
>>>
>>> On 5/14/25 14:01, Eric Auger wrote:
>>>> Move aml_pci_edsm to pcihp since we want to reuse that for
>>>> ARM and acpi-index support.
>>>>
>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>> ---
>>>>    include/hw/acpi/pcihp.h |  2 ++
>>>>    hw/acpi/pcihp.c         | 53 +++++++++++++++++++++++++++++++++++++++++
>>>>    hw/i386/acpi-build.c    | 53 -----------------------------------------
>>>>    3 files changed, 55 insertions(+), 53 deletions(-)
>>>>
>>>> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
>>>> index 4d820b4baf..bc31dbff39 100644
>>>> --- a/include/hw/acpi/pcihp.h
>>>> +++ b/include/hw/acpi/pcihp.h
>>>> @@ -82,6 +82,8 @@ bool build_append_notification_callback(Aml
>>>> *parent_scope, const PCIBus *bus);
>>>>      void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
>>>>    +Aml *aml_pci_edsm(void);
>>>> +
>>>>    /* Called on reset */
>>>>    void acpi_pcihp_reset(AcpiPciHpState *s);
>>>>    diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
>>>> index d800371ddc..57fe8938b1 100644
>>>> --- a/hw/acpi/pcihp.c
>>>> +++ b/hw/acpi/pcihp.c
>>>> @@ -937,6 +937,59 @@ void build_append_pci_bus_devices(Aml
>>>> *parent_scope, PCIBus *bus)
>>>>        }
>>>>    }
>>>>    +Aml *aml_pci_edsm(void)
>>>> +{
>>>> +    Aml *method, *ifctx;
>>>> +    Aml *zero = aml_int(0);
>>>> +    Aml *func = aml_arg(2);
>>>> +    Aml *ret = aml_local(0);
>>>> +    Aml *aidx = aml_local(1);
>>>> +    Aml *params = aml_arg(4);
>>>> +
>>>> +    method = aml_method("EDSM", 5, AML_SERIALIZED);
>>>> +
>>>> +    /* get supported functions */
>>>> +    ifctx = aml_if(aml_equal(func, zero));
>>>> +    {
>>>> +        /* 1: have supported functions */
>>>> +        /* 7: support for function 7 */
>>>> +        const uint8_t caps = 1 | BIT(7);
>>>> +        build_append_pci_dsm_func0_common(ifctx, ret);
>>>> +        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret,
>>>> zero)));
>>>> +        aml_append(ifctx, aml_return(ret));
>>>> +    }
>>>> +    aml_append(method, ifctx);
>>>> +
>>>> +    /* handle specific functions requests */
>>>> +    /*
>>>> +     * PCI Firmware Specification 3.1
>>>> +     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
>>>> +     *        Operating Systems
>>>> +     */
>>>> +    ifctx = aml_if(aml_equal(func, aml_int(7)));
>>>> +    {
>>>> +       Aml *pkg = aml_package(2);
>>>> +       aml_append(pkg, zero);
>>>> +       /* optional, if not impl. should return null string */
>>>> +       aml_append(pkg, aml_string("%s", ""));
>>>> +       aml_append(ifctx, aml_store(pkg, ret));
>>>> +
>>>> +       /*
>>>> +        * IASL is fine when initializing Package with computational
>>>> data,
>>>> +        * however it makes guest unhappy /it fails to process such
>>>> AML/.
>>>> +        * So use runtime assignment to set acpi-index after initializer
>>>> +        * to make OSPM happy.
>>>> +        */
>>>> +       aml_append(ifctx,
>>>> +           aml_store(aml_derefof(aml_index(params, aml_int(0))),
>>>> aidx));
>>>> +       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
>>>> +       aml_append(ifctx, aml_return(ret));
>>>> +    }
>>>> +    aml_append(method, ifctx);
>>>> +
>>>> +    return method;
>>>> +}
>>>> +
>>>>    const VMStateDescription vmstate_acpi_pcihp_pci_status = {
>>>>        .name = "acpi_pcihp_pci_status",
>>>>        .version_id = 1,
>>>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>>>> index bcfba2ccb3..385e75d061 100644
>>>> --- a/hw/i386/acpi-build.c
>>>> +++ b/hw/i386/acpi-build.c
>>>> @@ -322,59 +322,6 @@ build_facs(GArray *table_data)
>>>>        g_array_append_vals(table_data, reserved, 40); /* Reserved */
>>>>    }
>>>>    -static Aml *aml_pci_edsm(void)
>>>> -{
>>>> -    Aml *method, *ifctx;
>>>> -    Aml *zero = aml_int(0);
>>>> -    Aml *func = aml_arg(2);
>>>> -    Aml *ret = aml_local(0);
>>>> -    Aml *aidx = aml_local(1);
>>>> -    Aml *params = aml_arg(4);
>>>> -
>>>> -    method = aml_method("EDSM", 5, AML_SERIALIZED);
>>>> -
>>>> -    /* get supported functions */
>>>> -    ifctx = aml_if(aml_equal(func, zero));
>>>> -    {
>>>> -        /* 1: have supported functions */
>>>> -        /* 7: support for function 7 */
>>>> -        const uint8_t caps = 1 | BIT(7);
>>>> -        build_append_pci_dsm_func0_common(ifctx, ret);
>>>> -        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret,
>>>> zero)));
>>>> -        aml_append(ifctx, aml_return(ret));
>>>> -    }
>>>> -    aml_append(method, ifctx);
>>>> -
>>>> -    /* handle specific functions requests */
>>>> -    /*
>>>> -     * PCI Firmware Specification 3.1
>>>> -     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
>>>> -     *        Operating Systems
>>>> -     */
>>>> -    ifctx = aml_if(aml_equal(func, aml_int(7)));
>>>> -    {
>>>> -       Aml *pkg = aml_package(2);
>>>> -       aml_append(pkg, zero);
>>>> -       /* optional, if not impl. should return null string */
>>>> -       aml_append(pkg, aml_string("%s", ""));
>>>> -       aml_append(ifctx, aml_store(pkg, ret));
>>>> -
>>>> -       /*
>>>> -        * IASL is fine when initializing Package with computational
>>>> data,
>>>> -        * however it makes guest unhappy /it fails to process such
>>>> AML/.
>>>> -        * So use runtime assignment to set acpi-index after initializer
>>>> -        * to make OSPM happy.
>>>> -        */
>>>> -       aml_append(ifctx,
>>>> -           aml_store(aml_derefof(aml_index(params, aml_int(0))),
>>>> aidx));
>>>> -       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
>>>> -       aml_append(ifctx, aml_return(ret));
>>>> -    }
>>>> -    aml_append(method, ifctx);
>>>> -
>>>> -    return method;
>>>> -}
>>>> -
>>>>    /*
>>>>     * build_prt - Define interrupt routing rules
>>>>     *
>>>
>>> EDSM is not called from anywhere. _DSM method actually calls the PDSM,
>>> already defined
>>> in pcihp.c and generated by aml_pci_pdsm(). build_acpi_pci_hotplug(),
>>> which calls
>>> aml_pci_pdsm(), properly creates the PDSM method. Then in
>>> build_append_pcihp_slots()
>>> the a _DSM is defined per slot and inside it there is a call to PDSM,
>>> so I understand
>>> we should actually stick to the PDSM in pcihp.c instead of EDSM.
>>
>> I see build_append_pci_bus_devices -> aml_pci_static_endpoint_dsm
>> adds a _DSM method which eventually calls EDSM.
> 
> Yes, but I meant in the final generated ACPI AML code.
> 
> 
>> aml_pci_device_dsm builds another _DSM implementation which calls PDSM.
>>
>> As we use build_append_pci_bus_devices and we are likely to have a _DSM
>> implementation that calls EDSM method, I think we shall have it in the
>> aml. What do I miss?
> 
> Maybe some condition in build_append_pci_bus_devices() of:
> 
>          if (pdev->acpi_index &&
>              !object_property_get_bool(OBJECT(pdev), "hotpluggable",
>                                        &error_abort)) { ... }
> 
> 
> is not met?
> 
> Does your _DSM method in the machine's ACPI has a call to EDSM? I don't
> see it. In my case it's the PDSM that is being called:
> 
> gromero@xps13:/tmp$ grep -n PDSM dsdt.dsl
> 1910:        Method (PDSM, 5, Serialized)
> 2047:                    Return (PDSM (Arg0, Arg1, Arg2, Arg3, Local0))
> gromero@xps13:/tmp$ grep -n EDSM dsdt.dsl
> 1959:        Method (EDSM, 5, Serialized)
> gromero@xps13:/tmp$
> 
> I also confirmed that PDSM is what is being used by reverting this patch and
> dropping the aml_append(pci0_scope, aml_pci_edsm()); in 15/22.
> 
> But also, why shouldn't we use the PDSM defined already in pcihp.c? This is
> indeed crafted for the acpi-pcihp-hotplug device as I understand it.

Sorry, I see now, the EDSM is actually only for static endpoint PCI devices,
i.e. non-hotpluggable, I see. So PDSM and EDSM serve different purposes, although
similar.

So, my point in the end is (and the one that confused me too) that EDSM can be
present even if it will never be used by any static device, working pretty much
like an ACPI deadcode. Could we avoid this? For instance, just emit EDSM if
a _DSM that relies on it is emitted, like:

diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index e87846a1fa..4d6dd3dd96 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -905,8 +905,9 @@ void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus)
      aml_append(parent_scope, notify_method);
  }
  
-void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
+bool build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
  {
+    bool has_dsm = false;
      int devfn;
      Aml *dev;
  
@@ -929,11 +930,14 @@ void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
              !object_property_get_bool(OBJECT(pdev), "hotpluggable",
                                        &error_abort)) {
              aml_append(dev, aml_pci_static_endpoint_dsm(pdev));
+            has_dsm = true;
          }
  
          /* device descriptor has been composed, add it into parent context */
          aml_append(parent_scope, dev);
      }
+
+    return has_dsm;
  }
  
  Aml *aml_pci_edsm(void)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 05a754d368..e4788c03ed 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -844,15 +844,22 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
      if (vms->acpi_pcihp) {
          Aml *pci0_scope = aml_scope("\\_SB.PCI0");
  
-        aml_append(pci0_scope, aml_pci_edsm());
          build_acpi_pci_hotplug(dsdt, AML_SYSTEM_MEMORY,
                                 memmap[VIRT_ACPI_PCIHP].base);
          build_append_pcihp_resources(pci0_scope,
                                       memmap[VIRT_ACPI_PCIHP].base,
                                       memmap[VIRT_ACPI_PCIHP].size);
  
-        /* Scan all PCI buses. Generate tables to support hotplug. */
-        build_append_pci_bus_devices(pci0_scope, vms->bus);
+        /*
+         * Scan all PCI buses and devices. Generate tables to support static
+         * endpoint devices and hotplug.
+         */
+        /* Generate tables for static endpoints. */
+        if (build_append_pci_bus_devices(pci0_scope, vms->bus)) {
+            /* Has a _DSM method that requires a EDSM method. */
+            aml_append(pci0_scope, aml_pci_edsm());
+        }
+        /* Generate tables for PCI buses/slots/ */
          if (object_property_find(OBJECT(vms->bus), ACPI_PCIHP_PROP_BSEL)) {
              build_append_pcihp_slots(pci0_scope, vms->bus);
          }
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index bda5ea24b5..25cc39f4ab 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -82,7 +82,7 @@ void build_append_pcihp_resources(Aml *table,
                                    uint64_t io_addr, uint64_t io_len);
  bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus);
  
-void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
+bool build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
  
  Aml *aml_pci_edsm(void);


Another question that I have is: could you please share a QEMU command line option
that generates a static endpoint PCI device that matches the criteria for the emission
of the _DSM method accordingly to build_append_pci_bus_devices()?


Cheers,
Gustavo


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH 08/22] hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method
  2025-05-21 16:12     ` Eric Auger
@ 2025-05-24 10:54       ` Michael S. Tsirkin
  2025-05-26  9:16         ` Eric Auger
  0 siblings, 1 reply; 47+ messages in thread
From: Michael S. Tsirkin @ 2025-05-24 10:54 UTC (permalink / raw)
  To: Eric Auger
  Cc: Gustavo Romero, eric.auger.pro, qemu-devel, qemu-arm,
	peter.maydell, imammedo, anisinha, shannon.zhaosl, pbonzini,
	Jonathan.Cameron, philmd

On Wed, May 21, 2025 at 06:12:34PM +0200, Eric Auger wrote:
> Hi Gustavo,
> 
> On 5/20/25 4:09 PM, Gustavo Romero wrote:
> > Hi Eric,
> >
> > On 5/14/25 14:00, Eric Auger wrote:
> >> gpex build_host_bridge_osc() and x86 originated
> >> build_pci_host_bridge_osc_method() are mostly identical.
> >>
> >> In GPEX, SUPP is set to CDW2 but is not further used. CTRL
> >> is same as Local0.
> >>
> >> So let gpex code reuse build_pci_host_bridge_osc_method()
> >> and remove build_host_bridge_osc().
> >>
> >> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> >>
> >> ---
> >>
> >> The DSDT diff  is given below:
> >> diff --git a/dsdt.dsl_before b/dsdt.dsl_after_osc_change
> >> index 3224a56..fa7558e 100644
> >> --- a/dsdt.dsl_before
> >> +++ b/dsdt.dsl_after_osc_change
> >> @@ -5,13 +5,13 @@
> >>    *
> >>    * Disassembling to symbolic ASL+ operators
> >>    *
> >> - * Disassembly of dsdt.dat, Mon Apr  7 05:33:06 2025
> >> + * Disassembly of dsdt.dat, Mon Apr  7 05:37:20 2025
> >>    *
> >>    * Original Table Header:
> >>    *     Signature        "DSDT"
> >> - *     Length           0x00001A4F (6735)
> >> + *     Length           0x00001A35 (6709)
> >>    *     Revision         0x02
> >> - *     Checksum         0xBF
> >> + *     Checksum         0xDD
> >>    *     OEM ID           "BOCHS "
> >>    *     OEM Table ID     "BXPC    "
> >>    *     OEM Revision     0x00000001 (1)
> >> @@ -1849,27 +1849,26 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ",
> >> "BXPC    ", 0x00000001)
> >>                   {
> >>                       CreateDWordField (Arg3, 0x04, CDW2)
> >>                       CreateDWordField (Arg3, 0x08, CDW3)
> >> -                    SUPP = CDW2 /* \_SB_.PCI0._OSC.CDW2 */
> >> -                    CTRL = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
> >> -                    CTRL &= 0x1F
> >> +                    Local0 = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
> >> +                    Local0 &= 0x1F
> >>                       If ((Arg1 != One))
> >>                       {
> >>                           CDW1 |= 0x08
> >>                       }
> >>
> >> -                    If ((CDW3 != CTRL))
> >> +                    If ((CDW3 != Local0))
> >>                       {
> >>                           CDW1 |= 0x10
> >>                       }
> >>
> >> -                    CDW3 = CTRL /* \_SB_.PCI0.CTRL */
> >> -                    Return (Arg3)
> >> +                    CDW3 = Local0
> >>                   }
> >>                   Else
> >>                   {
> >>                       CDW1 |= 0x04
> >> -                    Return (Arg3)
> >>                   }
> >> +
> >> +                Return (Arg3)
> >>               }
> >>
> >>               Method (_DSM, 4, NotSerialized)  // _DSM:
> >> Device-Specific Method
> >
> > The problem I face with diffs in the commit body is that tools like
> > b4, which are
> > based on git am, get very confused on how to handle it. I'm surprised
> > nobody ever
> > complained about it. I'm wondering if there is any catch on it,
> > because I have to
> > edit commits like this manually, removing the diff, to make it finally
> > apply to
> > the series. Anyways, do you mind at least removing the valid diff
> > header, like:
> >
> >> diff --git a/dsdt.dsl_before b/dsdt.dsl_after_osc_change
> >> index 3224a56..fa7558e 100644
> >> --- a/dsdt.dsl_before
> >> +++ b/dsdt.dsl_after_osc_change
> >
> > from the commit message so it doesn't confuse b4?
> Thank you for reporting the issue. in tests/qtest/bios-tables-test.c it
> is written at the top that we shall put the diffs in disasembled ACPI
> content in the commit msg. I will look for previously landed patches and
> see whether the current layout can be fixed.
> 
> Cheers
> 
> Eric


Eric, to clarify, the diff is supposed to go into commit log,
not after ---.
This will make it apply cleanly.
Also, removing the "index" line as well as date diff at least is a good
idea: the diff should be clean, not include irrelevant information.

Pls feel free to clarify the text in tests/qtest/bios-tables-test.c



> >
> >
> >> ---
> >>   hw/pci-host/gpex-acpi.c | 60 +++--------------------------------------
> >>   1 file changed, 4 insertions(+), 56 deletions(-)
> >>
> >> diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
> >> index f1ab30f3d5..98c9868c3f 100644
> >> --- a/hw/pci-host/gpex-acpi.c
> >> +++ b/hw/pci-host/gpex-acpi.c
> >> @@ -50,60 +50,7 @@ static void acpi_dsdt_add_pci_route_table(Aml
> >> *dev, uint32_t irq,
> >>       }
> >>   }
> >>   -static Aml *build_host_bridge_osc(bool enable_native_pcie_hotplug)
> >> -{
> >> -    Aml *method, *UUID, *ifctx, *ifctx1, *elsectx;
> >> -
> >> -    method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
> >> -    aml_append(method,
> >> -        aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
> >> -
> >> -    /* PCI Firmware Specification 3.0
> >> -     * 4.5.1. _OSC Interface for PCI Host Bridge Devices
> >> -     * The _OSC interface for a PCI/PCI-X/PCI Express hierarchy is
> >> -     * identified by the Universal Unique IDentifier (UUID)
> >> -     * 33DB4D5B-1FF7-401C-9657-7441C03DD766
> >> -     */
> >> -    UUID = aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766");
> >> -    ifctx = aml_if(aml_equal(aml_arg(0), UUID));
> >> -    aml_append(ifctx,
> >> -        aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
> >> -    aml_append(ifctx,
> >> -        aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
> >> -    aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
> >> -    aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
> >> -
> >> -    /*
> >> -     * Allow OS control for SHPCHotplug, PME, AER, PCIeCapability,
> >> -     * and PCIeHotplug depending on enable_native_pcie_hotplug
> >> -     */
> >> -    aml_append(ifctx, aml_and(aml_name("CTRL"),
> >> -               aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 :
> >> 0x0)),
> >> -               aml_name("CTRL")));
> >> -
> >> -    ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
> >> -    aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
> >> -                              aml_name("CDW1")));
> >> -    aml_append(ifctx, ifctx1);
> >> -
> >> -    ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"),
> >> aml_name("CTRL"))));
> >> -    aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10),
> >> -                              aml_name("CDW1")));
> >> -    aml_append(ifctx, ifctx1);
> >> -
> >> -    aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
> >> -    aml_append(ifctx, aml_return(aml_arg(3)));
> >> -    aml_append(method, ifctx);
> >> -
> >> -    elsectx = aml_else();
> >> -    aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4),
> >> -                               aml_name("CDW1")));
> >> -    aml_append(elsectx, aml_return(aml_arg(3)));
> >> -    aml_append(method, elsectx);
> >> -    return method;
> >> -}
> >> -
> >> -static Aml *build_host_bridge_dsm(void)
> >> +static Aml *build_pci_host_bridge_dsm_method(void)
> >>   {
> >>       Aml *method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
> >>       Aml *UUID, *ifctx, *ifctx1, *buf;
> >> @@ -134,8 +81,9 @@ static void acpi_dsdt_add_host_bridge_methods(Aml
> >> *dev,
> >>       aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
> >>       aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
> >>       /* Declare an _OSC (OS Control Handoff) method */
> >> -    aml_append(dev, build_host_bridge_osc(enable_native_pcie_hotplug));
> >> -    aml_append(dev, build_host_bridge_dsm());
> >> +    aml_append(dev,
> >> +              
> >> build_pci_host_bridge_osc_method(enable_native_pcie_hotplug));
> >> +    aml_append(dev, build_pci_host_bridge_dsm_method());
> >>   }
> >>     void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
> >
> > Otherwise:
> >
> > Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>
> >
> >
> > Cheers,
> > Gustavo
> >



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 01/22] hw/i386/acpi-build: Make aml_pci_device_dsm() static
  2025-05-14 17:00 ` [PATCH 01/22] hw/i386/acpi-build: Make aml_pci_device_dsm() static Eric Auger
  2025-05-20 12:30   ` Gustavo Romero
@ 2025-05-25 15:29   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 47+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-05-25 15:29 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron

On 14/5/25 18:00, Eric Auger wrote:
> No need to export aml_pci_device_dsm() as it is only used
> in hw/i386/acpi-build.c.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>   include/hw/acpi/pci.h | 1 -
>   hw/i386/acpi-build.c  | 2 +-
>   2 files changed, 1 insertion(+), 2 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 16/22] hw/acpi/ged: Prepare the device to react to PCI hotplug events
  2025-05-14 17:01 ` [PATCH 16/22] hw/acpi/ged: Prepare the device to react to PCI hotplug events Eric Auger
@ 2025-05-25 15:34   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 47+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-05-25 15:34 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron

Hi Eric,

On 14/5/25 18:01, Eric Auger wrote:
> QEMU will notify the OS about PCI hotplug/hotunplug events through
> GED interrupts. Let the GED device handle a new PCI hotplug event.
> On its occurrence it calls the \\_SB.PCI0.PCNT method with the BLCK
> mutex held.
> 
> The GED device uses a dedicated MMIO region that will be mapped
> by the machine code.
> 
> At this point the GED still does not support PCI device hotplug in
> its TYPE_HOTPLUG_HANDLER implementation. This will come in a
> subsequent patch.
> 
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> ---
>   include/hw/acpi/generic_event_device.h |  5 +++++
>   include/hw/acpi/pcihp.h                |  2 ++
>   hw/acpi/generic_event_device.c         | 15 +++++++++++++++
>   hw/acpi/pcihp.c                        |  1 -
>   4 files changed, 22 insertions(+), 1 deletion(-)


> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
> index bc31dbff39..bda5ea24b5 100644
> --- a/include/hw/acpi/pcihp.h
> +++ b/include/hw/acpi/pcihp.h
> @@ -38,6 +38,8 @@
>   #define ACPI_PCIHP_SEJ_BASE 0x8
>   #define ACPI_PCIHP_BNMR_BASE 0x10
>   
> +#define ACPI_PCIHP_SIZE 0x0018
> +
>   typedef struct AcpiPciHpPciStatus {
>       uint32_t up;
>       uint32_t down;
> diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
> index 7a62f8d5bc..dc3620553d 100644
> --- a/hw/acpi/generic_event_device.c
> +++ b/hw/acpi/generic_event_device.c
> @@ -12,6 +12,7 @@
>   #include "qemu/osdep.h"
>   #include "qapi/error.h"
>   #include "hw/acpi/acpi.h"
> +#include "hw/acpi/pcihp.h"
>   #include "hw/acpi/generic_event_device.h"
>   #include "hw/irq.h"
>   #include "hw/mem/pc-dimm.h"
> @@ -26,6 +27,7 @@ static const uint32_t ged_supported_events[] = {
>       ACPI_GED_PWR_DOWN_EVT,
>       ACPI_GED_NVDIMM_HOTPLUG_EVT,
>       ACPI_GED_CPU_HOTPLUG_EVT,
> +    ACPI_GED_PCI_HOTPLUG_EVT,
>   };
>   
>   /*
> @@ -121,6 +123,12 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
>                              aml_notify(aml_name("\\_SB.NVDR"),
>                                         aml_int(0x80)));
>                   break;
> +            case ACPI_GED_PCI_HOTPLUG_EVT:
> +                aml_append(if_ctx,
> +                           aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF));
> +                aml_append(if_ctx, aml_call0("\\_SB.PCI0.PCNT"));
> +                aml_append(if_ctx, aml_release(aml_name("\\_SB.PCI0.BLCK")));
> +                break;
>               default:
>                   /*
>                    * Please make sure all the events in ged_supported_events[]
> @@ -299,6 +307,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
>           sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
>       } else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
>           sel = ACPI_GED_CPU_HOTPLUG_EVT;
> +    } else if (ev & ACPI_PCI_HOTPLUG_STATUS) {
> +        sel = ACPI_GED_PCI_HOTPLUG_EVT;
>       } else {
>           /* Unknown event. Return without generating interrupt. */
>           warn_report("GED: Unsupported event %d. No irq injected", ev);
> @@ -428,6 +438,11 @@ static void acpi_ged_realize(DeviceState *dev, Error **errp)
>               cpu_hotplug_hw_init(&s->container_cpuhp, OBJECT(dev),
>                                   &s->cpuhp_state, 0);
>               break;
> +        case ACPI_GED_PCI_HOTPLUG_EVT:
> +            memory_region_init(&s->container_pcihp, OBJECT(dev),
> +                                "pcihp container",

Since "pcihp container" isn't just a description anymore, can
we have a ACPI_PCIHP_REGION_NAME definition?

> +                                ACPI_PCIHP_SIZE);
> +            sysbus_init_mmio(sbd, &s->container_pcihp);
>           }
>           ged_events--;
>       }
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index 57fe8938b1..e87846a1fa 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -44,7 +44,6 @@
>   #include "qobject/qnum.h"
>   #include "trace.h"
>   
> -#define ACPI_PCIHP_SIZE 0x0018
>   #define PCI_UP_BASE 0x0000
>   #define PCI_DOWN_BASE 0x0004
>   #define PCI_EJ_BASE 0x0008



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 00/22] ACPI PCI Hotplug support on ARM
  2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
                   ` (21 preceding siblings ...)
  2025-05-14 17:01 ` [PATCH 22/22] hw/arm/virt: Use ACPI PCI hotplug by default Eric Auger
@ 2025-05-26  5:55 ` Gustavo Romero
  2025-05-26 10:21   ` Eric Auger
  22 siblings, 1 reply; 47+ messages in thread
From: Gustavo Romero @ 2025-05-26  5:55 UTC (permalink / raw)
  To: Eric Auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/14/25 14:00, Eric Auger wrote:
> This series enables ACPI PCI hotplug/hotunplug on ARM
> and makes it default for 10.1 machine type. This aligns with
> x86 q35 machine. Expected benefits should be similar to
> those listed in [1].
> 
> It is still possible to disable it using a virt machine
> option: virt,acpi-pcihp=off and restore the legacy behavior.
> 
> The infrastructure used in x86 is heavily reused and a
> huge part of the series consists in moving code from
> hw/i386/acpi-build.c to a generic place and slightly
> adapting it to make it usable on ARM. The DSDT table is
> augmented to support ACPI PCI hotplug elements.
> 
> On ARM we use use a GED event to notify the OS about
> hotplug events.
> 
> I have not noticed any tests/qtest/bios-tables-test failures
> neither on x86 nor ARM. x86 DSDT table has not changed.
> ARM DSDT table definitively has but there are no tests
> impacted. ARM misses hotplug tests that do exist on x86. This
> most probably should be considered in the future.

I've just posted a v1 for a acpi-pcihp=on test:

https://mail.gnu.org/archive/html/qemu-devel/2025-05/msg05824.html

The odd thing is that I noticed failures in the existing aarch64
acpi tests in tests/qtest/bios-tables-test. At least the rename
of the variable 'CTRL' to 'Local0' in the _OSC method should cause
a mismatch against the current base DSDT? So I had to handle it
via patches 1/5, 2/5, and 3/5. The diff is in the 3/5 commit body.


Cheers,
Gustavo

> Best Regards
> 
> Eric
> 
> This series can be found at:
> https://github.com/eauger/qemu/tree/arm-acpi-pcihp-v1
> 
> previous RFC:
> https://github.com/eauger/qemu/tree/arm-acpi-pcihp-rfc
> 
> History:
> RFC -> v1:
> - First 3 trivial patches were pulled separately
> - Fix of the register region size (0x18), ie. ACPI_PCIHP_SIZE
> - addition of aml_pci_edsm which was not called in RFC
> - acpi-index feature is now fixed. vms->bus was not set on
>    acpi_pcihp_init. The init sequence is still hacky though. Suggestions
>    appreciated.
> 
> [1] [PATCH v6 0/6] Use ACPI PCI hot-plug for Q35
> https://lore.kernel.org/all/20210713004205.775386-1-jusual@redhat.com/
> 
> 
> Eric Auger (22):
>    hw/i386/acpi-build: Make aml_pci_device_dsm() static
>    hw/arm/virt: Introduce machine state acpi pcihp flags and props
>    hw/acpi: Rename and move build_x86_acpi_pci_hotplug to pcihp
>    hw/pci-host/gpex-acpi: Add native_pci_hotplug arg to
>      acpi_dsdt_add_pci_osc
>    hw/pci-host/gpex-acpi: Split host bridge OSC and DSM generation
>    hw/pci-host/gpex-acpi: Propagate hotplug type info from virt machine
>      downto gpex
>    hw/i386/acpi-build: Turn build_q35_osc_method into a generic method
>    hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method
>    hw/i386/acpi-build: Introduce build_append_pcihp_resources() helper
>    hw/acpi/pcihp: Add an AmlRegionSpace arg to build_acpi_pci_hotplug
>    hw/i386/acpi-build: Move build_append_notification_callback to pcihp
>    hw/i386/acpi-build: Move build_append_pci_bus_devices/pcihp_slots to
>      pcihp
>    hw/i386/acpi-build: Introduce and use acpi_get_pci_host
>    hw/i386/acpi-build: Move aml_pci_edsm to a generic place
>    hw/arm/virt-acpi-build: Modify the DSDT ACPI table to enable ACPI PCI
>      hotplug
>    hw/acpi/ged: Prepare the device to react to PCI hotplug events
>    hw/acpi/ged: Call pcihp plug callbacks in hotplug handler
>      implementation
>    hw/acpi/ged: Support migration of AcpiPciHpState
>    hw/core/sysbus: Introduce sysbus_mmio_map_name() helper
>    hw/arm/virt: Let virt support pci hotplug/unplug GED event
>    hw/arm/virt: Plug pcihp hotplug/hotunplug callbacks
>    hw/arm/virt: Use ACPI PCI hotplug by default
> 
>   hw/i386/acpi-build.h                   |   4 -
>   include/hw/acpi/aml-build.h            |   2 +
>   include/hw/acpi/generic_event_device.h |   5 +
>   include/hw/acpi/pci.h                  |   4 +-
>   include/hw/acpi/pcihp.h                |  19 +-
>   include/hw/arm/virt.h                  |   4 +
>   include/hw/pci-host/gpex.h             |   1 +
>   include/hw/sysbus.h                    |   1 +
>   hw/acpi/aml-build.c                    |  50 +++
>   hw/acpi/generic_event_device.c         |  55 +++
>   hw/acpi/pci.c                          |  20 +
>   hw/acpi/pcihp.c                        | 482 ++++++++++++++++++++-
>   hw/arm/virt-acpi-build.c               |  27 ++
>   hw/arm/virt.c                          | 107 ++++-
>   hw/core/sysbus.c                       |  11 +
>   hw/i386/acpi-build.c                   | 552 +------------------------
>   hw/pci-host/gpex-acpi.c                |  75 +---
>   hw/arm/Kconfig                         |   2 +
>   18 files changed, 806 insertions(+), 615 deletions(-)
> 



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 13/22] hw/i386/acpi-build: Introduce and use acpi_get_pci_host
  2025-05-20 20:00   ` Gustavo Romero
@ 2025-05-26  9:16     ` Eric Auger
  0 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-26  9:16 UTC (permalink / raw)
  To: Gustavo Romero, eric.auger.pro, qemu-devel, qemu-arm,
	peter.maydell, imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd



On 5/20/25 10:00 PM, Gustavo Romero wrote:
> Hi Eric,
>
> On 5/14/25 14:01, Eric Auger wrote:
>> pcihp acpi_set_pci_info() generic code currently uses
>> acpi_get_i386_pci_host() to retrieve the pci host bridge.
>>
>> Let's rename acpi_get_i386_pci_host into acpi_get_pci_host and
>> move it in pci generic code.
>>
>> The helper is augmented with the support of ARM GPEX.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>> ---
>>   include/hw/acpi/pci.h |  2 ++
>>   hw/acpi/pci.c         | 20 ++++++++++++++++++++
>>   hw/acpi/pcihp.c       |  3 ++-
>>   hw/i386/acpi-build.c  | 24 ++++--------------------
>>   4 files changed, 28 insertions(+), 21 deletions(-)
>>
>> diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h
>> index 4dca22c0e2..310cbd02db 100644
>> --- a/include/hw/acpi/pci.h
>> +++ b/include/hw/acpi/pci.h
>> @@ -41,4 +41,6 @@ void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml
>> *scope);
>>     void build_srat_generic_affinity_structures(GArray *table_data);
>>   +Object *acpi_get_pci_host(void);
>> +
>>   #endif
>> diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c
>> index d511a85029..4191886ebe 100644
>> --- a/hw/acpi/pci.c
>> +++ b/hw/acpi/pci.c
>> @@ -26,6 +26,7 @@
>>   #include "qemu/osdep.h"
>>   #include "qemu/error-report.h"
>>   #include "qom/object_interfaces.h"
>> +#include "qom/object.h"
>>   #include "qapi/error.h"
>>   #include "hw/boards.h"
>>   #include "hw/acpi/aml-build.h"
>> @@ -33,6 +34,9 @@
>>   #include "hw/pci/pci_bridge.h"
>>   #include "hw/pci/pci_device.h"
>>   #include "hw/pci/pcie_host.h"
>> +#include "hw/pci-host/i440fx.h"
>> +#include "hw/pci-host/q35.h"
>> +#include "hw/pci-host/gpex.h"
>>     /*
>>    * PCI Firmware Specification, Revision 3.0
>> @@ -301,3 +305,19 @@ void
>> build_srat_generic_affinity_structures(GArray *table_data)
>>       object_child_foreach_recursive(object_get_root(),
>> build_acpi_generic_port,
>>                                      table_data);
>>   }
>> +
>> +Object *acpi_get_pci_host(void)
>> +{
>> +    Object *host;
>> +
>> +    host =
>> object_resolve_type_unambiguous(TYPE_I440FX_PCI_HOST_BRIDGE, NULL);
>> +    if (host) {
>> +        return host;
>> +    }
>> +    host = object_resolve_type_unambiguous(TYPE_Q35_HOST_DEVICE, NULL);
>> +    if (host) {
>> +        return host;
>> +    }
>> +    host = object_resolve_type_unambiguous(TYPE_GPEX_HOST, NULL);
>> +    return host;
>> +}
>> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
>> index 942669ea89..d800371ddc 100644
>> --- a/hw/acpi/pcihp.c
>> +++ b/hw/acpi/pcihp.c
>> @@ -36,6 +36,7 @@
>>   #include "hw/pci-bridge/xio3130_downstream.h"
>>   #include "hw/i386/acpi-build.h"
>>   #include "hw/acpi/acpi.h"
>> +#include "hw/acpi/pci.h"
>>   #include "hw/pci/pci_bus.h"
>>   #include "migration/vmstate.h"
>>   #include "qapi/error.h"
>> @@ -102,7 +103,7 @@ static void *acpi_set_bsel(PCIBus *bus, void
>> *opaque)
>>   static void acpi_set_pci_info(bool has_bridge_hotplug)
>>   {
>>       static bool bsel_is_set;
>> -    Object *host = acpi_get_i386_pci_host();
>> +    Object *host = acpi_get_pci_host();
>>       PCIBus *bus;
>>       BSELInfo info = { .bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT,
>>                         .has_bridge_hotplug = has_bridge_hotplug };
>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>> index 06b4b8eed4..bcfba2ccb3 100644
>> --- a/hw/i386/acpi-build.c
>> +++ b/hw/i386/acpi-build.c
>> @@ -269,27 +269,11 @@ static void acpi_get_misc_info(AcpiMiscInfo *info)
>>   #endif
>>   }
>>   -/*
>> - * Because of the PXB hosts we cannot simply query
>> TYPE_PCI_HOST_BRIDGE.
>> - * On i386 arch we only have two pci hosts, so we can look only for
>> them.
>> - */
>> -Object *acpi_get_i386_pci_host(void)
>> -{
>> -    PCIHostState *host;
>> -
>> -    host = PCI_HOST_BRIDGE(object_resolve_path("/machine/i440fx",
>> NULL));
>> -    if (!host) {
>> -        host = PCI_HOST_BRIDGE(object_resolve_path("/machine/q35",
>> NULL));
>> -    }
>> -
>> -    return OBJECT(host);
>> -}
>> -
>
> It's also possible to add a child prop to the TYPE_GPEX_HOST in
> create_pcie, like:
>
> @@ -1510,6 +1510,7 @@ static void create_pcie(VirtMachineState *vms)
>      MachineClass *mc = MACHINE_GET_CLASS(ms);
>  
>      dev = qdev_new(TYPE_GPEX_HOST);
> +    object_property_add_child(OBJECT(vms), "gpex", OBJECT(dev));
>
> then follow to logic in acpi_get_i386_pci_host via:
>
> PCI_HOST_BRIDGE(object_resolve_path("/machine/gpex", NULL))
indeed
>
> but I like better your solution of using the final class types, so:
>
> Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>

OK thanks! I described that change in the commit msg because it was
effectively not properly described.

Cheers

Eric
>
>
> Cheers,
> Gustavo
>
>>   static void acpi_get_pci_holes(Range *hole, Range *hole64)
>>   {
>>       Object *pci_host;
>>   -    pci_host = acpi_get_i386_pci_host();
>> +    pci_host = acpi_get_pci_host();
>>         if (!pci_host) {
>>           return;
>> @@ -1245,7 +1229,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>>         sb_scope = aml_scope("\\_SB");
>>       {
>> -        Object *pci_host = acpi_get_i386_pci_host();
>> +        Object *pci_host = acpi_get_pci_host();
>>             if (pci_host) {
>>               PCIBus *pbus = PCI_HOST_BRIDGE(pci_host)->bus;
>> @@ -1306,7 +1290,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
>>       if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
>>           bool has_pcnt;
>>   -        Object *pci_host = acpi_get_i386_pci_host();
>> +        Object *pci_host = acpi_get_pci_host();
>>           PCIBus *b = PCI_HOST_BRIDGE(pci_host)->bus;
>>             scope = aml_scope("\\_SB.PCI0");
>> @@ -1946,7 +1930,7 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
>>       Object *pci_host;
>>       QObject *o;
>>   -    pci_host = acpi_get_i386_pci_host();
>> +    pci_host = acpi_get_pci_host();
>>       if (!pci_host) {
>>           return false;
>>       }
>



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 08/22] hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method
  2025-05-24 10:54       ` Michael S. Tsirkin
@ 2025-05-26  9:16         ` Eric Auger
  0 siblings, 0 replies; 47+ messages in thread
From: Eric Auger @ 2025-05-26  9:16 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Gustavo Romero, eric.auger.pro, qemu-devel, qemu-arm,
	peter.maydell, imammedo, anisinha, shannon.zhaosl, pbonzini,
	Jonathan.Cameron, philmd

Hi Michael, Gustavo,

On 5/24/25 12:54 PM, Michael S. Tsirkin wrote:
> On Wed, May 21, 2025 at 06:12:34PM +0200, Eric Auger wrote:
>> Hi Gustavo,
>>
>> On 5/20/25 4:09 PM, Gustavo Romero wrote:
>>> Hi Eric,
>>>
>>> On 5/14/25 14:00, Eric Auger wrote:
>>>> gpex build_host_bridge_osc() and x86 originated
>>>> build_pci_host_bridge_osc_method() are mostly identical.
>>>>
>>>> In GPEX, SUPP is set to CDW2 but is not further used. CTRL
>>>> is same as Local0.
>>>>
>>>> So let gpex code reuse build_pci_host_bridge_osc_method()
>>>> and remove build_host_bridge_osc().
>>>>
>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>>
>>>> ---
>>>>
>>>> The DSDT diff  is given below:
>>>> diff --git a/dsdt.dsl_before b/dsdt.dsl_after_osc_change
>>>> index 3224a56..fa7558e 100644
>>>> --- a/dsdt.dsl_before
>>>> +++ b/dsdt.dsl_after_osc_change
>>>> @@ -5,13 +5,13 @@
>>>>    *
>>>>    * Disassembling to symbolic ASL+ operators
>>>>    *
>>>> - * Disassembly of dsdt.dat, Mon Apr  7 05:33:06 2025
>>>> + * Disassembly of dsdt.dat, Mon Apr  7 05:37:20 2025
>>>>    *
>>>>    * Original Table Header:
>>>>    *     Signature        "DSDT"
>>>> - *     Length           0x00001A4F (6735)
>>>> + *     Length           0x00001A35 (6709)
>>>>    *     Revision         0x02
>>>> - *     Checksum         0xBF
>>>> + *     Checksum         0xDD
>>>>    *     OEM ID           "BOCHS "
>>>>    *     OEM Table ID     "BXPC    "
>>>>    *     OEM Revision     0x00000001 (1)
>>>> @@ -1849,27 +1849,26 @@ DefinitionBlock ("", "DSDT", 2, "BOCHS ",
>>>> "BXPC    ", 0x00000001)
>>>>                   {
>>>>                       CreateDWordField (Arg3, 0x04, CDW2)
>>>>                       CreateDWordField (Arg3, 0x08, CDW3)
>>>> -                    SUPP = CDW2 /* \_SB_.PCI0._OSC.CDW2 */
>>>> -                    CTRL = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
>>>> -                    CTRL &= 0x1F
>>>> +                    Local0 = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
>>>> +                    Local0 &= 0x1F
>>>>                       If ((Arg1 != One))
>>>>                       {
>>>>                           CDW1 |= 0x08
>>>>                       }
>>>>
>>>> -                    If ((CDW3 != CTRL))
>>>> +                    If ((CDW3 != Local0))
>>>>                       {
>>>>                           CDW1 |= 0x10
>>>>                       }
>>>>
>>>> -                    CDW3 = CTRL /* \_SB_.PCI0.CTRL */
>>>> -                    Return (Arg3)
>>>> +                    CDW3 = Local0
>>>>                   }
>>>>                   Else
>>>>                   {
>>>>                       CDW1 |= 0x04
>>>> -                    Return (Arg3)
>>>>                   }
>>>> +
>>>> +                Return (Arg3)
>>>>               }
>>>>
>>>>               Method (_DSM, 4, NotSerialized)  // _DSM:
>>>> Device-Specific Method
>>> The problem I face with diffs in the commit body is that tools like
>>> b4, which are
>>> based on git am, get very confused on how to handle it. I'm surprised
>>> nobody ever
>>> complained about it. I'm wondering if there is any catch on it,
>>> because I have to
>>> edit commits like this manually, removing the diff, to make it finally
>>> apply to
>>> the series. Anyways, do you mind at least removing the valid diff
>>> header, like:
>>>
>>>> diff --git a/dsdt.dsl_before b/dsdt.dsl_after_osc_change
>>>> index 3224a56..fa7558e 100644
>>>> --- a/dsdt.dsl_before
>>>> +++ b/dsdt.dsl_after_osc_change
>>> from the commit message so it doesn't confuse b4?
>> Thank you for reporting the issue. in tests/qtest/bios-tables-test.c it
>> is written at the top that we shall put the diffs in disasembled ACPI
>> content in the commit msg. I will look for previously landed patches and
>> see whether the current layout can be fixed.
>>
>> Cheers
>>
>> Eric
>
> Eric, to clarify, the diff is supposed to go into commit log,
> not after ---.
> This will make it apply cleanly.
> Also, removing the "index" line as well as date diff at least is a good
> idea: the diff should be clean, not include irrelevant information.
>
> Pls feel free to clarify the text in tests/qtest/bios-tables-test.c

Of thanks. I applied your suggestions.

Eric
>
>
>
>>>
>>>> ---
>>>>   hw/pci-host/gpex-acpi.c | 60 +++--------------------------------------
>>>>   1 file changed, 4 insertions(+), 56 deletions(-)
>>>>
>>>> diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c
>>>> index f1ab30f3d5..98c9868c3f 100644
>>>> --- a/hw/pci-host/gpex-acpi.c
>>>> +++ b/hw/pci-host/gpex-acpi.c
>>>> @@ -50,60 +50,7 @@ static void acpi_dsdt_add_pci_route_table(Aml
>>>> *dev, uint32_t irq,
>>>>       }
>>>>   }
>>>>   -static Aml *build_host_bridge_osc(bool enable_native_pcie_hotplug)
>>>> -{
>>>> -    Aml *method, *UUID, *ifctx, *ifctx1, *elsectx;
>>>> -
>>>> -    method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
>>>> -    aml_append(method,
>>>> -        aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
>>>> -
>>>> -    /* PCI Firmware Specification 3.0
>>>> -     * 4.5.1. _OSC Interface for PCI Host Bridge Devices
>>>> -     * The _OSC interface for a PCI/PCI-X/PCI Express hierarchy is
>>>> -     * identified by the Universal Unique IDentifier (UUID)
>>>> -     * 33DB4D5B-1FF7-401C-9657-7441C03DD766
>>>> -     */
>>>> -    UUID = aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766");
>>>> -    ifctx = aml_if(aml_equal(aml_arg(0), UUID));
>>>> -    aml_append(ifctx,
>>>> -        aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
>>>> -    aml_append(ifctx,
>>>> -        aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
>>>> -    aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
>>>> -    aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
>>>> -
>>>> -    /*
>>>> -     * Allow OS control for SHPCHotplug, PME, AER, PCIeCapability,
>>>> -     * and PCIeHotplug depending on enable_native_pcie_hotplug
>>>> -     */
>>>> -    aml_append(ifctx, aml_and(aml_name("CTRL"),
>>>> -               aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 :
>>>> 0x0)),
>>>> -               aml_name("CTRL")));
>>>> -
>>>> -    ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
>>>> -    aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
>>>> -                              aml_name("CDW1")));
>>>> -    aml_append(ifctx, ifctx1);
>>>> -
>>>> -    ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"),
>>>> aml_name("CTRL"))));
>>>> -    aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10),
>>>> -                              aml_name("CDW1")));
>>>> -    aml_append(ifctx, ifctx1);
>>>> -
>>>> -    aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
>>>> -    aml_append(ifctx, aml_return(aml_arg(3)));
>>>> -    aml_append(method, ifctx);
>>>> -
>>>> -    elsectx = aml_else();
>>>> -    aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4),
>>>> -                               aml_name("CDW1")));
>>>> -    aml_append(elsectx, aml_return(aml_arg(3)));
>>>> -    aml_append(method, elsectx);
>>>> -    return method;
>>>> -}
>>>> -
>>>> -static Aml *build_host_bridge_dsm(void)
>>>> +static Aml *build_pci_host_bridge_dsm_method(void)
>>>>   {
>>>>       Aml *method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
>>>>       Aml *UUID, *ifctx, *ifctx1, *buf;
>>>> @@ -134,8 +81,9 @@ static void acpi_dsdt_add_host_bridge_methods(Aml
>>>> *dev,
>>>>       aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
>>>>       aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
>>>>       /* Declare an _OSC (OS Control Handoff) method */
>>>> -    aml_append(dev, build_host_bridge_osc(enable_native_pcie_hotplug));
>>>> -    aml_append(dev, build_host_bridge_dsm());
>>>> +    aml_append(dev,
>>>> +              
>>>> build_pci_host_bridge_osc_method(enable_native_pcie_hotplug));
>>>> +    aml_append(dev, build_pci_host_bridge_dsm_method());
>>>>   }
>>>>     void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
>>> Otherwise:
>>>
>>> Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>
>>>
>>>
>>> Cheers,
>>> Gustavo
>>>



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 00/22] ACPI PCI Hotplug support on ARM
  2025-05-26  5:55 ` [PATCH 00/22] ACPI PCI Hotplug support on ARM Gustavo Romero
@ 2025-05-26 10:21   ` Eric Auger
  2025-05-26 13:56     ` Gustavo Romero
  0 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-26 10:21 UTC (permalink / raw)
  To: Gustavo Romero, eric.auger.pro, qemu-devel, qemu-arm,
	peter.maydell, imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Gustavo,

On 5/26/25 7:55 AM, Gustavo Romero wrote:
> Hi Eric,
>
> On 5/14/25 14:00, Eric Auger wrote:
>> This series enables ACPI PCI hotplug/hotunplug on ARM
>> and makes it default for 10.1 machine type. This aligns with
>> x86 q35 machine. Expected benefits should be similar to
>> those listed in [1].
>>
>> It is still possible to disable it using a virt machine
>> option: virt,acpi-pcihp=off and restore the legacy behavior.
>>
>> The infrastructure used in x86 is heavily reused and a
>> huge part of the series consists in moving code from
>> hw/i386/acpi-build.c to a generic place and slightly
>> adapting it to make it usable on ARM. The DSDT table is
>> augmented to support ACPI PCI hotplug elements.
>>
>> On ARM we use use a GED event to notify the OS about
>> hotplug events.
>>
>> I have not noticed any tests/qtest/bios-tables-test failures
>> neither on x86 nor ARM. x86 DSDT table has not changed.
>> ARM DSDT table definitively has but there are no tests
>> impacted. ARM misses hotplug tests that do exist on x86. This
>> most probably should be considered in the future.
>
> I've just posted a v1 for a acpi-pcihp=on test:
>
> https://mail.gnu.org/archive/html/qemu-devel/2025-05/msg05824.html
>
> The odd thing is that I noticed failures in the existing aarch64
> acpi tests in tests/qtest/bios-tables-test. At least the rename
> of the variable 'CTRL' to 'Local0' in the _OSC method should cause
> a mismatch against the current base DSDT? So I had to handle it
> via patches 1/5, 2/5, and 3/5. The diff is in the 3/5 commit body.

Thank you for contributing those tests.

Hum I think my mistake was to have executed the existing tests in KVM
acceleration mode only using
QTEST_QEMU_BINARY=qemu-system-aarch64 tests/qtest/bios-tables-test
direct execution.

The failing tests belong to the TCG category I think.

I will review your tests and if you allow me I may need to include
patches 1 and 3 in my series to prevent existing tests from failing, of
course with all your credits.

Thank you again for reporting the issue!

Eric




>
> Cheers,
> Gustavo
>
>> Best Regards
>>
>> Eric
>>
>> This series can be found at:
>> https://github.com/eauger/qemu/tree/arm-acpi-pcihp-v1
>>
>> previous RFC:
>> https://github.com/eauger/qemu/tree/arm-acpi-pcihp-rfc
>>
>> History:
>> RFC -> v1:
>> - First 3 trivial patches were pulled separately
>> - Fix of the register region size (0x18), ie. ACPI_PCIHP_SIZE
>> - addition of aml_pci_edsm which was not called in RFC
>> - acpi-index feature is now fixed. vms->bus was not set on
>>    acpi_pcihp_init. The init sequence is still hacky though. Suggestions
>>    appreciated.
>>
>> [1] [PATCH v6 0/6] Use ACPI PCI hot-plug for Q35
>> https://lore.kernel.org/all/20210713004205.775386-1-jusual@redhat.com/
>>
>>
>> Eric Auger (22):
>>    hw/i386/acpi-build: Make aml_pci_device_dsm() static
>>    hw/arm/virt: Introduce machine state acpi pcihp flags and props
>>    hw/acpi: Rename and move build_x86_acpi_pci_hotplug to pcihp
>>    hw/pci-host/gpex-acpi: Add native_pci_hotplug arg to
>>      acpi_dsdt_add_pci_osc
>>    hw/pci-host/gpex-acpi: Split host bridge OSC and DSM generation
>>    hw/pci-host/gpex-acpi: Propagate hotplug type info from virt machine
>>      downto gpex
>>    hw/i386/acpi-build: Turn build_q35_osc_method into a generic method
>>    hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method
>>    hw/i386/acpi-build: Introduce build_append_pcihp_resources() helper
>>    hw/acpi/pcihp: Add an AmlRegionSpace arg to build_acpi_pci_hotplug
>>    hw/i386/acpi-build: Move build_append_notification_callback to pcihp
>>    hw/i386/acpi-build: Move build_append_pci_bus_devices/pcihp_slots to
>>      pcihp
>>    hw/i386/acpi-build: Introduce and use acpi_get_pci_host
>>    hw/i386/acpi-build: Move aml_pci_edsm to a generic place
>>    hw/arm/virt-acpi-build: Modify the DSDT ACPI table to enable ACPI PCI
>>      hotplug
>>    hw/acpi/ged: Prepare the device to react to PCI hotplug events
>>    hw/acpi/ged: Call pcihp plug callbacks in hotplug handler
>>      implementation
>>    hw/acpi/ged: Support migration of AcpiPciHpState
>>    hw/core/sysbus: Introduce sysbus_mmio_map_name() helper
>>    hw/arm/virt: Let virt support pci hotplug/unplug GED event
>>    hw/arm/virt: Plug pcihp hotplug/hotunplug callbacks
>>    hw/arm/virt: Use ACPI PCI hotplug by default
>>
>>   hw/i386/acpi-build.h                   |   4 -
>>   include/hw/acpi/aml-build.h            |   2 +
>>   include/hw/acpi/generic_event_device.h |   5 +
>>   include/hw/acpi/pci.h                  |   4 +-
>>   include/hw/acpi/pcihp.h                |  19 +-
>>   include/hw/arm/virt.h                  |   4 +
>>   include/hw/pci-host/gpex.h             |   1 +
>>   include/hw/sysbus.h                    |   1 +
>>   hw/acpi/aml-build.c                    |  50 +++
>>   hw/acpi/generic_event_device.c         |  55 +++
>>   hw/acpi/pci.c                          |  20 +
>>   hw/acpi/pcihp.c                        | 482 ++++++++++++++++++++-
>>   hw/arm/virt-acpi-build.c               |  27 ++
>>   hw/arm/virt.c                          | 107 ++++-
>>   hw/core/sysbus.c                       |  11 +
>>   hw/i386/acpi-build.c                   | 552 +------------------------
>>   hw/pci-host/gpex-acpi.c                |  75 +---
>>   hw/arm/Kconfig                         |   2 +
>>   18 files changed, 806 insertions(+), 615 deletions(-)
>>
>



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 00/22] ACPI PCI Hotplug support on ARM
  2025-05-26 10:21   ` Eric Auger
@ 2025-05-26 13:56     ` Gustavo Romero
  0 siblings, 0 replies; 47+ messages in thread
From: Gustavo Romero @ 2025-05-26 13:56 UTC (permalink / raw)
  To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/26/25 07:21, Eric Auger wrote:
> Hi Gustavo,
> 
> On 5/26/25 7:55 AM, Gustavo Romero wrote:
>> Hi Eric,
>>
>> On 5/14/25 14:00, Eric Auger wrote:
>>> This series enables ACPI PCI hotplug/hotunplug on ARM
>>> and makes it default for 10.1 machine type. This aligns with
>>> x86 q35 machine. Expected benefits should be similar to
>>> those listed in [1].
>>>
>>> It is still possible to disable it using a virt machine
>>> option: virt,acpi-pcihp=off and restore the legacy behavior.
>>>
>>> The infrastructure used in x86 is heavily reused and a
>>> huge part of the series consists in moving code from
>>> hw/i386/acpi-build.c to a generic place and slightly
>>> adapting it to make it usable on ARM. The DSDT table is
>>> augmented to support ACPI PCI hotplug elements.
>>>
>>> On ARM we use use a GED event to notify the OS about
>>> hotplug events.
>>>
>>> I have not noticed any tests/qtest/bios-tables-test failures
>>> neither on x86 nor ARM. x86 DSDT table has not changed.
>>> ARM DSDT table definitively has but there are no tests
>>> impacted. ARM misses hotplug tests that do exist on x86. This
>>> most probably should be considered in the future.
>>
>> I've just posted a v1 for a acpi-pcihp=on test:
>>
>> https://mail.gnu.org/archive/html/qemu-devel/2025-05/msg05824.html
>>
>> The odd thing is that I noticed failures in the existing aarch64
>> acpi tests in tests/qtest/bios-tables-test. At least the rename
>> of the variable 'CTRL' to 'Local0' in the _OSC method should cause
>> a mismatch against the current base DSDT? So I had to handle it
>> via patches 1/5, 2/5, and 3/5. The diff is in the 3/5 commit body.
> 
> Thank you for contributing those tests.
> 
> Hum I think my mistake was to have executed the existing tests in KVM
> acceleration mode only using
> QTEST_QEMU_BINARY=qemu-system-aarch64 tests/qtest/bios-tables-test
> direct execution.
> 
> The failing tests belong to the TCG category I think.
> 
> I will review your tests and if you allow me I may need to include
> patches 1 and 3 in my series to prevent existing tests from failing, of
> course with all your credits.

Yeah, absolutely!

I left some comments on you comments in 3/5 in [0] about the organization
and sequence of the patches, but I think we're in sync :)

[0] https://mail.gnu.org/archive/html/qemu-devel/2025-05/msg05824.html


> Thank you again for reporting the issue!

Np! Glad to help :)


Cheers,
Gustavo
  
> Eric
> 
> 
> 
> 
>>
>> Cheers,
>> Gustavo
>>
>>> Best Regards
>>>
>>> Eric
>>>
>>> This series can be found at:
>>> https://github.com/eauger/qemu/tree/arm-acpi-pcihp-v1
>>>
>>> previous RFC:
>>> https://github.com/eauger/qemu/tree/arm-acpi-pcihp-rfc
>>>
>>> History:
>>> RFC -> v1:
>>> - First 3 trivial patches were pulled separately
>>> - Fix of the register region size (0x18), ie. ACPI_PCIHP_SIZE
>>> - addition of aml_pci_edsm which was not called in RFC
>>> - acpi-index feature is now fixed. vms->bus was not set on
>>>     acpi_pcihp_init. The init sequence is still hacky though. Suggestions
>>>     appreciated.
>>>
>>> [1] [PATCH v6 0/6] Use ACPI PCI hot-plug for Q35
>>> https://lore.kernel.org/all/20210713004205.775386-1-jusual@redhat.com/
>>>
>>>
>>> Eric Auger (22):
>>>     hw/i386/acpi-build: Make aml_pci_device_dsm() static
>>>     hw/arm/virt: Introduce machine state acpi pcihp flags and props
>>>     hw/acpi: Rename and move build_x86_acpi_pci_hotplug to pcihp
>>>     hw/pci-host/gpex-acpi: Add native_pci_hotplug arg to
>>>       acpi_dsdt_add_pci_osc
>>>     hw/pci-host/gpex-acpi: Split host bridge OSC and DSM generation
>>>     hw/pci-host/gpex-acpi: Propagate hotplug type info from virt machine
>>>       downto gpex
>>>     hw/i386/acpi-build: Turn build_q35_osc_method into a generic method
>>>     hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method
>>>     hw/i386/acpi-build: Introduce build_append_pcihp_resources() helper
>>>     hw/acpi/pcihp: Add an AmlRegionSpace arg to build_acpi_pci_hotplug
>>>     hw/i386/acpi-build: Move build_append_notification_callback to pcihp
>>>     hw/i386/acpi-build: Move build_append_pci_bus_devices/pcihp_slots to
>>>       pcihp
>>>     hw/i386/acpi-build: Introduce and use acpi_get_pci_host
>>>     hw/i386/acpi-build: Move aml_pci_edsm to a generic place
>>>     hw/arm/virt-acpi-build: Modify the DSDT ACPI table to enable ACPI PCI
>>>       hotplug
>>>     hw/acpi/ged: Prepare the device to react to PCI hotplug events
>>>     hw/acpi/ged: Call pcihp plug callbacks in hotplug handler
>>>       implementation
>>>     hw/acpi/ged: Support migration of AcpiPciHpState
>>>     hw/core/sysbus: Introduce sysbus_mmio_map_name() helper
>>>     hw/arm/virt: Let virt support pci hotplug/unplug GED event
>>>     hw/arm/virt: Plug pcihp hotplug/hotunplug callbacks
>>>     hw/arm/virt: Use ACPI PCI hotplug by default
>>>
>>>    hw/i386/acpi-build.h                   |   4 -
>>>    include/hw/acpi/aml-build.h            |   2 +
>>>    include/hw/acpi/generic_event_device.h |   5 +
>>>    include/hw/acpi/pci.h                  |   4 +-
>>>    include/hw/acpi/pcihp.h                |  19 +-
>>>    include/hw/arm/virt.h                  |   4 +
>>>    include/hw/pci-host/gpex.h             |   1 +
>>>    include/hw/sysbus.h                    |   1 +
>>>    hw/acpi/aml-build.c                    |  50 +++
>>>    hw/acpi/generic_event_device.c         |  55 +++
>>>    hw/acpi/pci.c                          |  20 +
>>>    hw/acpi/pcihp.c                        | 482 ++++++++++++++++++++-
>>>    hw/arm/virt-acpi-build.c               |  27 ++
>>>    hw/arm/virt.c                          | 107 ++++-
>>>    hw/core/sysbus.c                       |  11 +
>>>    hw/i386/acpi-build.c                   | 552 +------------------------
>>>    hw/pci-host/gpex-acpi.c                |  75 +---
>>>    hw/arm/Kconfig                         |   2 +
>>>    18 files changed, 806 insertions(+), 615 deletions(-)
>>>
>>
> 



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place
  2025-05-21 20:19         ` Gustavo Romero
@ 2025-05-27  7:18           ` Eric Auger
  2025-05-27 19:34             ` Gustavo Romero
  0 siblings, 1 reply; 47+ messages in thread
From: Eric Auger @ 2025-05-27  7:18 UTC (permalink / raw)
  To: Gustavo Romero, eric.auger.pro, qemu-devel, qemu-arm,
	peter.maydell, imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd



On 5/21/25 10:19 PM, Gustavo Romero wrote:
> Hi Eric,
>
> On 5/21/25 13:24, Gustavo Romero wrote:
>> Hi Eric,
>>
>> On 5/21/25 12:56, Eric Auger wrote:
>>> Hi Gustavo,
>>>
>>> On 5/21/25 5:26 PM, Gustavo Romero wrote:
>>>> Hi Eric,
>>>>
>>>> On 5/14/25 14:01, Eric Auger wrote:
>>>>> Move aml_pci_edsm to pcihp since we want to reuse that for
>>>>> ARM and acpi-index support.
>>>>>
>>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>>> ---
>>>>>    include/hw/acpi/pcihp.h |  2 ++
>>>>>    hw/acpi/pcihp.c         | 53
>>>>> +++++++++++++++++++++++++++++++++++++++++
>>>>>    hw/i386/acpi-build.c    | 53
>>>>> -----------------------------------------
>>>>>    3 files changed, 55 insertions(+), 53 deletions(-)
>>>>>
>>>>> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
>>>>> index 4d820b4baf..bc31dbff39 100644
>>>>> --- a/include/hw/acpi/pcihp.h
>>>>> +++ b/include/hw/acpi/pcihp.h
>>>>> @@ -82,6 +82,8 @@ bool build_append_notification_callback(Aml
>>>>> *parent_scope, const PCIBus *bus);
>>>>>      void build_append_pci_bus_devices(Aml *parent_scope, PCIBus
>>>>> *bus);
>>>>>    +Aml *aml_pci_edsm(void);
>>>>> +
>>>>>    /* Called on reset */
>>>>>    void acpi_pcihp_reset(AcpiPciHpState *s);
>>>>>    diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
>>>>> index d800371ddc..57fe8938b1 100644
>>>>> --- a/hw/acpi/pcihp.c
>>>>> +++ b/hw/acpi/pcihp.c
>>>>> @@ -937,6 +937,59 @@ void build_append_pci_bus_devices(Aml
>>>>> *parent_scope, PCIBus *bus)
>>>>>        }
>>>>>    }
>>>>>    +Aml *aml_pci_edsm(void)
>>>>> +{
>>>>> +    Aml *method, *ifctx;
>>>>> +    Aml *zero = aml_int(0);
>>>>> +    Aml *func = aml_arg(2);
>>>>> +    Aml *ret = aml_local(0);
>>>>> +    Aml *aidx = aml_local(1);
>>>>> +    Aml *params = aml_arg(4);
>>>>> +
>>>>> +    method = aml_method("EDSM", 5, AML_SERIALIZED);
>>>>> +
>>>>> +    /* get supported functions */
>>>>> +    ifctx = aml_if(aml_equal(func, zero));
>>>>> +    {
>>>>> +        /* 1: have supported functions */
>>>>> +        /* 7: support for function 7 */
>>>>> +        const uint8_t caps = 1 | BIT(7);
>>>>> +        build_append_pci_dsm_func0_common(ifctx, ret);
>>>>> +        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret,
>>>>> zero)));
>>>>> +        aml_append(ifctx, aml_return(ret));
>>>>> +    }
>>>>> +    aml_append(method, ifctx);
>>>>> +
>>>>> +    /* handle specific functions requests */
>>>>> +    /*
>>>>> +     * PCI Firmware Specification 3.1
>>>>> +     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
>>>>> +     *        Operating Systems
>>>>> +     */
>>>>> +    ifctx = aml_if(aml_equal(func, aml_int(7)));
>>>>> +    {
>>>>> +       Aml *pkg = aml_package(2);
>>>>> +       aml_append(pkg, zero);
>>>>> +       /* optional, if not impl. should return null string */
>>>>> +       aml_append(pkg, aml_string("%s", ""));
>>>>> +       aml_append(ifctx, aml_store(pkg, ret));
>>>>> +
>>>>> +       /*
>>>>> +        * IASL is fine when initializing Package with computational
>>>>> data,
>>>>> +        * however it makes guest unhappy /it fails to process such
>>>>> AML/.
>>>>> +        * So use runtime assignment to set acpi-index after
>>>>> initializer
>>>>> +        * to make OSPM happy.
>>>>> +        */
>>>>> +       aml_append(ifctx,
>>>>> +           aml_store(aml_derefof(aml_index(params, aml_int(0))),
>>>>> aidx));
>>>>> +       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
>>>>> +       aml_append(ifctx, aml_return(ret));
>>>>> +    }
>>>>> +    aml_append(method, ifctx);
>>>>> +
>>>>> +    return method;
>>>>> +}
>>>>> +
>>>>>    const VMStateDescription vmstate_acpi_pcihp_pci_status = {
>>>>>        .name = "acpi_pcihp_pci_status",
>>>>>        .version_id = 1,
>>>>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>>>>> index bcfba2ccb3..385e75d061 100644
>>>>> --- a/hw/i386/acpi-build.c
>>>>> +++ b/hw/i386/acpi-build.c
>>>>> @@ -322,59 +322,6 @@ build_facs(GArray *table_data)
>>>>>        g_array_append_vals(table_data, reserved, 40); /* Reserved */
>>>>>    }
>>>>>    -static Aml *aml_pci_edsm(void)
>>>>> -{
>>>>> -    Aml *method, *ifctx;
>>>>> -    Aml *zero = aml_int(0);
>>>>> -    Aml *func = aml_arg(2);
>>>>> -    Aml *ret = aml_local(0);
>>>>> -    Aml *aidx = aml_local(1);
>>>>> -    Aml *params = aml_arg(4);
>>>>> -
>>>>> -    method = aml_method("EDSM", 5, AML_SERIALIZED);
>>>>> -
>>>>> -    /* get supported functions */
>>>>> -    ifctx = aml_if(aml_equal(func, zero));
>>>>> -    {
>>>>> -        /* 1: have supported functions */
>>>>> -        /* 7: support for function 7 */
>>>>> -        const uint8_t caps = 1 | BIT(7);
>>>>> -        build_append_pci_dsm_func0_common(ifctx, ret);
>>>>> -        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret,
>>>>> zero)));
>>>>> -        aml_append(ifctx, aml_return(ret));
>>>>> -    }
>>>>> -    aml_append(method, ifctx);
>>>>> -
>>>>> -    /* handle specific functions requests */
>>>>> -    /*
>>>>> -     * PCI Firmware Specification 3.1
>>>>> -     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
>>>>> -     *        Operating Systems
>>>>> -     */
>>>>> -    ifctx = aml_if(aml_equal(func, aml_int(7)));
>>>>> -    {
>>>>> -       Aml *pkg = aml_package(2);
>>>>> -       aml_append(pkg, zero);
>>>>> -       /* optional, if not impl. should return null string */
>>>>> -       aml_append(pkg, aml_string("%s", ""));
>>>>> -       aml_append(ifctx, aml_store(pkg, ret));
>>>>> -
>>>>> -       /*
>>>>> -        * IASL is fine when initializing Package with computational
>>>>> data,
>>>>> -        * however it makes guest unhappy /it fails to process such
>>>>> AML/.
>>>>> -        * So use runtime assignment to set acpi-index after
>>>>> initializer
>>>>> -        * to make OSPM happy.
>>>>> -        */
>>>>> -       aml_append(ifctx,
>>>>> -           aml_store(aml_derefof(aml_index(params, aml_int(0))),
>>>>> aidx));
>>>>> -       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
>>>>> -       aml_append(ifctx, aml_return(ret));
>>>>> -    }
>>>>> -    aml_append(method, ifctx);
>>>>> -
>>>>> -    return method;
>>>>> -}
>>>>> -
>>>>>    /*
>>>>>     * build_prt - Define interrupt routing rules
>>>>>     *
>>>>
>>>> EDSM is not called from anywhere. _DSM method actually calls the PDSM,
>>>> already defined
>>>> in pcihp.c and generated by aml_pci_pdsm(). build_acpi_pci_hotplug(),
>>>> which calls
>>>> aml_pci_pdsm(), properly creates the PDSM method. Then in
>>>> build_append_pcihp_slots()
>>>> the a _DSM is defined per slot and inside it there is a call to PDSM,
>>>> so I understand
>>>> we should actually stick to the PDSM in pcihp.c instead of EDSM.
>>>
>>> I see build_append_pci_bus_devices -> aml_pci_static_endpoint_dsm
>>> adds a _DSM method which eventually calls EDSM.
>>
>> Yes, but I meant in the final generated ACPI AML code.
>>
>>
>>> aml_pci_device_dsm builds another _DSM implementation which calls PDSM.
>>>
>>> As we use build_append_pci_bus_devices and we are likely to have a _DSM
>>> implementation that calls EDSM method, I think we shall have it in the
>>> aml. What do I miss?
>>
>> Maybe some condition in build_append_pci_bus_devices() of:
>>
>>          if (pdev->acpi_index &&
>>              !object_property_get_bool(OBJECT(pdev), "hotpluggable",
>>                                        &error_abort)) { ... }
>>
>>
>> is not met?
>>
>> Does your _DSM method in the machine's ACPI has a call to EDSM? I don't
>> see it. In my case it's the PDSM that is being called:
>>
>> gromero@xps13:/tmp$ grep -n PDSM dsdt.dsl
>> 1910:        Method (PDSM, 5, Serialized)
>> 2047:                    Return (PDSM (Arg0, Arg1, Arg2, Arg3, Local0))
>> gromero@xps13:/tmp$ grep -n EDSM dsdt.dsl
>> 1959:        Method (EDSM, 5, Serialized)
>> gromero@xps13:/tmp$
>>
>> I also confirmed that PDSM is what is being used by reverting this
>> patch and
>> dropping the aml_append(pci0_scope, aml_pci_edsm()); in 15/22.
>>
>> But also, why shouldn't we use the PDSM defined already in pcihp.c?
>> This is
>> indeed crafted for the acpi-pcihp-hotplug device as I understand it.
>
> Sorry, I see now, the EDSM is actually only for static endpoint PCI
> devices,
> i.e. non-hotpluggable, I see. So PDSM and EDSM serve different
> purposes, although
> similar.
>
> So, my point in the end is (and the one that confused me too) that
> EDSM can be
> present even if it will never be used by any static device, working
> pretty much
> like an ACPI deadcode. Could we avoid this? For instance, just emit
> EDSM if
> a _DSM that relies on it is emitted, like:

I see your point and it's true that for some PCIe configs the code can
be there while not used. However it looks it is done the same way on x86
and I would tend to be not more popish than the pope ;-)

Maybe this can be a patch sent afterwards that would also address the
x86 case then.
>
> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index e87846a1fa..4d6dd3dd96 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -905,8 +905,9 @@ void build_append_pcihp_slots(Aml *parent_scope,
> PCIBus *bus)
>      aml_append(parent_scope, notify_method);
>  }
>  
> -void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
> +bool build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
>  {
> +    bool has_dsm = false;
>      int devfn;
>      Aml *dev;
>  
> @@ -929,11 +930,14 @@ void build_append_pci_bus_devices(Aml
> *parent_scope, PCIBus *bus)
>              !object_property_get_bool(OBJECT(pdev), "hotpluggable",
>                                        &error_abort)) {
>              aml_append(dev, aml_pci_static_endpoint_dsm(pdev));
> +            has_dsm = true;
>          }
>  
>          /* device descriptor has been composed, add it into parent
> context */
>          aml_append(parent_scope, dev);
>      }
> +
> +    return has_dsm;
>  }
>  
>  Aml *aml_pci_edsm(void)
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 05a754d368..e4788c03ed 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -844,15 +844,22 @@ build_dsdt(GArray *table_data, BIOSLinker
> *linker, VirtMachineState *vms)
>      if (vms->acpi_pcihp) {
>          Aml *pci0_scope = aml_scope("\\_SB.PCI0");
>  
> -        aml_append(pci0_scope, aml_pci_edsm());
>          build_acpi_pci_hotplug(dsdt, AML_SYSTEM_MEMORY,
>                                 memmap[VIRT_ACPI_PCIHP].base);
>          build_append_pcihp_resources(pci0_scope,
>                                       memmap[VIRT_ACPI_PCIHP].base,
>                                       memmap[VIRT_ACPI_PCIHP].size);
>  
> -        /* Scan all PCI buses. Generate tables to support hotplug. */
> -        build_append_pci_bus_devices(pci0_scope, vms->bus);
> +        /*
> +         * Scan all PCI buses and devices. Generate tables to support
> static
> +         * endpoint devices and hotplug.
> +         */
> +        /* Generate tables for static endpoints. */
> +        if (build_append_pci_bus_devices(pci0_scope, vms->bus)) {
> +            /* Has a _DSM method that requires a EDSM method. */
> +            aml_append(pci0_scope, aml_pci_edsm());
> +        }
> +        /* Generate tables for PCI buses/slots/ */
>          if (object_property_find(OBJECT(vms->bus),
> ACPI_PCIHP_PROP_BSEL)) {
>              build_append_pcihp_slots(pci0_scope, vms->bus);
>          }
> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
> index bda5ea24b5..25cc39f4ab 100644
> --- a/include/hw/acpi/pcihp.h
> +++ b/include/hw/acpi/pcihp.h
> @@ -82,7 +82,7 @@ void build_append_pcihp_resources(Aml *table,
>                                    uint64_t io_addr, uint64_t io_len);
>  bool build_append_notification_callback(Aml *parent_scope, const
> PCIBus *bus);
>  
> -void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
> +bool build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
>  
>  Aml *aml_pci_edsm(void);
>
>
> Another question that I have is: could you please share a QEMU command
> line option
> that generates a static endpoint PCI device that matches the criteria
> for the emission
> of the _DSM method accordingly to build_append_pci_bus_devices()?
You can instantiate a virtio-net-pci device on pci.0 and with acpi-index
set.

-device
virtio-net-pci,bus=pcie.0,netdev=nic0,mac=6a:f5:10:b1:3d:d2,acpi-index=12

In that case EDSM is being called:

        Device (S08)
        {
            Name (_ADR, 0x00010000)  // _ADR: Address
            Method (_DSM, 4, Serialized)  // _DSM: Device-Specific Method
            {
                Local0 = Package (0x01)
                    {
                        0x0C
                    }
                Return (EDSM (Arg0, Arg1, Arg2, Arg3, Local0))
            }
        }

Putting it on a root port will let the EDSM unused.

Cheers

Eric


>
>
> Cheers,
> Gustavo
>



^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place
  2025-05-27  7:18           ` Eric Auger
@ 2025-05-27 19:34             ` Gustavo Romero
  0 siblings, 0 replies; 47+ messages in thread
From: Gustavo Romero @ 2025-05-27 19:34 UTC (permalink / raw)
  To: eric.auger, eric.auger.pro, qemu-devel, qemu-arm, peter.maydell,
	imammedo, anisinha, mst, shannon.zhaosl
  Cc: pbonzini, Jonathan.Cameron, philmd

Hi Eric,

On 5/27/25 04:18, Eric Auger wrote:
> 
> 
> On 5/21/25 10:19 PM, Gustavo Romero wrote:
>> Hi Eric,
>>
>> On 5/21/25 13:24, Gustavo Romero wrote:
>>> Hi Eric,
>>>
>>> On 5/21/25 12:56, Eric Auger wrote:
>>>> Hi Gustavo,
>>>>
>>>> On 5/21/25 5:26 PM, Gustavo Romero wrote:
>>>>> Hi Eric,
>>>>>
>>>>> On 5/14/25 14:01, Eric Auger wrote:
>>>>>> Move aml_pci_edsm to pcihp since we want to reuse that for
>>>>>> ARM and acpi-index support.
>>>>>>
>>>>>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>>>>> ---
>>>>>>     include/hw/acpi/pcihp.h |  2 ++
>>>>>>     hw/acpi/pcihp.c         | 53
>>>>>> +++++++++++++++++++++++++++++++++++++++++
>>>>>>     hw/i386/acpi-build.c    | 53
>>>>>> -----------------------------------------
>>>>>>     3 files changed, 55 insertions(+), 53 deletions(-)
>>>>>>
>>>>>> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
>>>>>> index 4d820b4baf..bc31dbff39 100644
>>>>>> --- a/include/hw/acpi/pcihp.h
>>>>>> +++ b/include/hw/acpi/pcihp.h
>>>>>> @@ -82,6 +82,8 @@ bool build_append_notification_callback(Aml
>>>>>> *parent_scope, const PCIBus *bus);
>>>>>>       void build_append_pci_bus_devices(Aml *parent_scope, PCIBus
>>>>>> *bus);
>>>>>>     +Aml *aml_pci_edsm(void);
>>>>>> +
>>>>>>     /* Called on reset */
>>>>>>     void acpi_pcihp_reset(AcpiPciHpState *s);
>>>>>>     diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
>>>>>> index d800371ddc..57fe8938b1 100644
>>>>>> --- a/hw/acpi/pcihp.c
>>>>>> +++ b/hw/acpi/pcihp.c
>>>>>> @@ -937,6 +937,59 @@ void build_append_pci_bus_devices(Aml
>>>>>> *parent_scope, PCIBus *bus)
>>>>>>         }
>>>>>>     }
>>>>>>     +Aml *aml_pci_edsm(void)
>>>>>> +{
>>>>>> +    Aml *method, *ifctx;
>>>>>> +    Aml *zero = aml_int(0);
>>>>>> +    Aml *func = aml_arg(2);
>>>>>> +    Aml *ret = aml_local(0);
>>>>>> +    Aml *aidx = aml_local(1);
>>>>>> +    Aml *params = aml_arg(4);
>>>>>> +
>>>>>> +    method = aml_method("EDSM", 5, AML_SERIALIZED);
>>>>>> +
>>>>>> +    /* get supported functions */
>>>>>> +    ifctx = aml_if(aml_equal(func, zero));
>>>>>> +    {
>>>>>> +        /* 1: have supported functions */
>>>>>> +        /* 7: support for function 7 */
>>>>>> +        const uint8_t caps = 1 | BIT(7);
>>>>>> +        build_append_pci_dsm_func0_common(ifctx, ret);
>>>>>> +        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret,
>>>>>> zero)));
>>>>>> +        aml_append(ifctx, aml_return(ret));
>>>>>> +    }
>>>>>> +    aml_append(method, ifctx);
>>>>>> +
>>>>>> +    /* handle specific functions requests */
>>>>>> +    /*
>>>>>> +     * PCI Firmware Specification 3.1
>>>>>> +     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
>>>>>> +     *        Operating Systems
>>>>>> +     */
>>>>>> +    ifctx = aml_if(aml_equal(func, aml_int(7)));
>>>>>> +    {
>>>>>> +       Aml *pkg = aml_package(2);
>>>>>> +       aml_append(pkg, zero);
>>>>>> +       /* optional, if not impl. should return null string */
>>>>>> +       aml_append(pkg, aml_string("%s", ""));
>>>>>> +       aml_append(ifctx, aml_store(pkg, ret));
>>>>>> +
>>>>>> +       /*
>>>>>> +        * IASL is fine when initializing Package with computational
>>>>>> data,
>>>>>> +        * however it makes guest unhappy /it fails to process such
>>>>>> AML/.
>>>>>> +        * So use runtime assignment to set acpi-index after
>>>>>> initializer
>>>>>> +        * to make OSPM happy.
>>>>>> +        */
>>>>>> +       aml_append(ifctx,
>>>>>> +           aml_store(aml_derefof(aml_index(params, aml_int(0))),
>>>>>> aidx));
>>>>>> +       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
>>>>>> +       aml_append(ifctx, aml_return(ret));
>>>>>> +    }
>>>>>> +    aml_append(method, ifctx);
>>>>>> +
>>>>>> +    return method;
>>>>>> +}
>>>>>> +
>>>>>>     const VMStateDescription vmstate_acpi_pcihp_pci_status = {
>>>>>>         .name = "acpi_pcihp_pci_status",
>>>>>>         .version_id = 1,
>>>>>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>>>>>> index bcfba2ccb3..385e75d061 100644
>>>>>> --- a/hw/i386/acpi-build.c
>>>>>> +++ b/hw/i386/acpi-build.c
>>>>>> @@ -322,59 +322,6 @@ build_facs(GArray *table_data)
>>>>>>         g_array_append_vals(table_data, reserved, 40); /* Reserved */
>>>>>>     }
>>>>>>     -static Aml *aml_pci_edsm(void)
>>>>>> -{
>>>>>> -    Aml *method, *ifctx;
>>>>>> -    Aml *zero = aml_int(0);
>>>>>> -    Aml *func = aml_arg(2);
>>>>>> -    Aml *ret = aml_local(0);
>>>>>> -    Aml *aidx = aml_local(1);
>>>>>> -    Aml *params = aml_arg(4);
>>>>>> -
>>>>>> -    method = aml_method("EDSM", 5, AML_SERIALIZED);
>>>>>> -
>>>>>> -    /* get supported functions */
>>>>>> -    ifctx = aml_if(aml_equal(func, zero));
>>>>>> -    {
>>>>>> -        /* 1: have supported functions */
>>>>>> -        /* 7: support for function 7 */
>>>>>> -        const uint8_t caps = 1 | BIT(7);
>>>>>> -        build_append_pci_dsm_func0_common(ifctx, ret);
>>>>>> -        aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret,
>>>>>> zero)));
>>>>>> -        aml_append(ifctx, aml_return(ret));
>>>>>> -    }
>>>>>> -    aml_append(method, ifctx);
>>>>>> -
>>>>>> -    /* handle specific functions requests */
>>>>>> -    /*
>>>>>> -     * PCI Firmware Specification 3.1
>>>>>> -     * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
>>>>>> -     *        Operating Systems
>>>>>> -     */
>>>>>> -    ifctx = aml_if(aml_equal(func, aml_int(7)));
>>>>>> -    {
>>>>>> -       Aml *pkg = aml_package(2);
>>>>>> -       aml_append(pkg, zero);
>>>>>> -       /* optional, if not impl. should return null string */
>>>>>> -       aml_append(pkg, aml_string("%s", ""));
>>>>>> -       aml_append(ifctx, aml_store(pkg, ret));
>>>>>> -
>>>>>> -       /*
>>>>>> -        * IASL is fine when initializing Package with computational
>>>>>> data,
>>>>>> -        * however it makes guest unhappy /it fails to process such
>>>>>> AML/.
>>>>>> -        * So use runtime assignment to set acpi-index after
>>>>>> initializer
>>>>>> -        * to make OSPM happy.
>>>>>> -        */
>>>>>> -       aml_append(ifctx,
>>>>>> -           aml_store(aml_derefof(aml_index(params, aml_int(0))),
>>>>>> aidx));
>>>>>> -       aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
>>>>>> -       aml_append(ifctx, aml_return(ret));
>>>>>> -    }
>>>>>> -    aml_append(method, ifctx);
>>>>>> -
>>>>>> -    return method;
>>>>>> -}
>>>>>> -
>>>>>>     /*
>>>>>>      * build_prt - Define interrupt routing rules
>>>>>>      *
>>>>>
>>>>> EDSM is not called from anywhere. _DSM method actually calls the PDSM,
>>>>> already defined
>>>>> in pcihp.c and generated by aml_pci_pdsm(). build_acpi_pci_hotplug(),
>>>>> which calls
>>>>> aml_pci_pdsm(), properly creates the PDSM method. Then in
>>>>> build_append_pcihp_slots()
>>>>> the a _DSM is defined per slot and inside it there is a call to PDSM,
>>>>> so I understand
>>>>> we should actually stick to the PDSM in pcihp.c instead of EDSM.
>>>>
>>>> I see build_append_pci_bus_devices -> aml_pci_static_endpoint_dsm
>>>> adds a _DSM method which eventually calls EDSM.
>>>
>>> Yes, but I meant in the final generated ACPI AML code.
>>>
>>>
>>>> aml_pci_device_dsm builds another _DSM implementation which calls PDSM.
>>>>
>>>> As we use build_append_pci_bus_devices and we are likely to have a _DSM
>>>> implementation that calls EDSM method, I think we shall have it in the
>>>> aml. What do I miss?
>>>
>>> Maybe some condition in build_append_pci_bus_devices() of:
>>>
>>>           if (pdev->acpi_index &&
>>>               !object_property_get_bool(OBJECT(pdev), "hotpluggable",
>>>                                         &error_abort)) { ... }
>>>
>>>
>>> is not met?
>>>
>>> Does your _DSM method in the machine's ACPI has a call to EDSM? I don't
>>> see it. In my case it's the PDSM that is being called:
>>>
>>> gromero@xps13:/tmp$ grep -n PDSM dsdt.dsl
>>> 1910:        Method (PDSM, 5, Serialized)
>>> 2047:                    Return (PDSM (Arg0, Arg1, Arg2, Arg3, Local0))
>>> gromero@xps13:/tmp$ grep -n EDSM dsdt.dsl
>>> 1959:        Method (EDSM, 5, Serialized)
>>> gromero@xps13:/tmp$
>>>
>>> I also confirmed that PDSM is what is being used by reverting this
>>> patch and
>>> dropping the aml_append(pci0_scope, aml_pci_edsm()); in 15/22.
>>>
>>> But also, why shouldn't we use the PDSM defined already in pcihp.c?
>>> This is
>>> indeed crafted for the acpi-pcihp-hotplug device as I understand it.
>>
>> Sorry, I see now, the EDSM is actually only for static endpoint PCI
>> devices,
>> i.e. non-hotpluggable, I see. So PDSM and EDSM serve different
>> purposes, although
>> similar.
>>
>> So, my point in the end is (and the one that confused me too) that
>> EDSM can be
>> present even if it will never be used by any static device, working
>> pretty much
>> like an ACPI deadcode. Could we avoid this? For instance, just emit
>> EDSM if
>> a _DSM that relies on it is emitted, like:
> 
> I see your point and it's true that for some PCIe configs the code can
> be there while not used. However it looks it is done the same way on x86
> and I would tend to be not more popish than the pope ;-)
> 
> Maybe this can be a patch sent afterwards that would also address the
> x86 case then.

Got it. Well, I think it's just a matter of making build_append_pci_bus_devices()
tell if any static endpoint is added and just call aml_pci_edsm() to emit EDSM if
there is any, like in my diff:

+        /* Generate tables for static endpoints. */
+        if (build_append_pci_bus_devices(pci0_scope, vms->bus)) {
+            /* Has a _DSM method that requires a EDSM method. */
+            aml_append(pci0_scope, aml_pci_edsm());
+        }

But I'm not really the maintainer or the official reviewer for this part of
the code, and you certainly have more karma than I do in this area, so it's
up to you, of course. I just think ACPI code is tricky enough to review,
and having dead code makes it a tad more daunting :)


>>
>> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
>> index e87846a1fa..4d6dd3dd96 100644
>> --- a/hw/acpi/pcihp.c
>> +++ b/hw/acpi/pcihp.c
>> @@ -905,8 +905,9 @@ void build_append_pcihp_slots(Aml *parent_scope,
>> PCIBus *bus)
>>       aml_append(parent_scope, notify_method);
>>   }
>>   
>> -void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
>> +bool build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
>>   {
>> +    bool has_dsm = false;
>>       int devfn;
>>       Aml *dev;
>>   
>> @@ -929,11 +930,14 @@ void build_append_pci_bus_devices(Aml
>> *parent_scope, PCIBus *bus)
>>               !object_property_get_bool(OBJECT(pdev), "hotpluggable",
>>                                         &error_abort)) {
>>               aml_append(dev, aml_pci_static_endpoint_dsm(pdev));
>> +            has_dsm = true;
>>           }
>>   
>>           /* device descriptor has been composed, add it into parent
>> context */
>>           aml_append(parent_scope, dev);
>>       }
>> +
>> +    return has_dsm;
>>   }
>>   
>>   Aml *aml_pci_edsm(void)
>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>> index 05a754d368..e4788c03ed 100644
>> --- a/hw/arm/virt-acpi-build.c
>> +++ b/hw/arm/virt-acpi-build.c
>> @@ -844,15 +844,22 @@ build_dsdt(GArray *table_data, BIOSLinker
>> *linker, VirtMachineState *vms)
>>       if (vms->acpi_pcihp) {
>>           Aml *pci0_scope = aml_scope("\\_SB.PCI0");
>>   
>> -        aml_append(pci0_scope, aml_pci_edsm());
>>           build_acpi_pci_hotplug(dsdt, AML_SYSTEM_MEMORY,
>>                                  memmap[VIRT_ACPI_PCIHP].base);
>>           build_append_pcihp_resources(pci0_scope,
>>                                        memmap[VIRT_ACPI_PCIHP].base,
>>                                        memmap[VIRT_ACPI_PCIHP].size);
>>   
>> -        /* Scan all PCI buses. Generate tables to support hotplug. */
>> -        build_append_pci_bus_devices(pci0_scope, vms->bus);
>> +        /*
>> +         * Scan all PCI buses and devices. Generate tables to support
>> static
>> +         * endpoint devices and hotplug.
>> +         */
>> +        /* Generate tables for static endpoints. */
>> +        if (build_append_pci_bus_devices(pci0_scope, vms->bus)) {
>> +            /* Has a _DSM method that requires a EDSM method. */
>> +            aml_append(pci0_scope, aml_pci_edsm());
>> +        }
>> +        /* Generate tables for PCI buses/slots/ */
>>           if (object_property_find(OBJECT(vms->bus),
>> ACPI_PCIHP_PROP_BSEL)) {
>>               build_append_pcihp_slots(pci0_scope, vms->bus);
>>           }
>> diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
>> index bda5ea24b5..25cc39f4ab 100644
>> --- a/include/hw/acpi/pcihp.h
>> +++ b/include/hw/acpi/pcihp.h
>> @@ -82,7 +82,7 @@ void build_append_pcihp_resources(Aml *table,
>>                                     uint64_t io_addr, uint64_t io_len);
>>   bool build_append_notification_callback(Aml *parent_scope, const
>> PCIBus *bus);
>>   
>> -void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
>> +bool build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus);
>>   
>>   Aml *aml_pci_edsm(void);
>>
>>
>> Another question that I have is: could you please share a QEMU command
>> line option
>> that generates a static endpoint PCI device that matches the criteria
>> for the emission
>> of the _DSM method accordingly to build_append_pci_bus_devices()?
> You can instantiate a virtio-net-pci device on pci.0 and with acpi-index
> set.
> 
> -device
> virtio-net-pci,bus=pcie.0,netdev=nic0,mac=6a:f5:10:b1:3d:d2,acpi-index=12
> 
> In that case EDSM is being called:
> 
>          Device (S08)
>          {
>              Name (_ADR, 0x00010000)  // _ADR: Address
>              Method (_DSM, 4, Serialized)  // _DSM: Device-Specific Method
>              {
>                  Local0 = Package (0x01)
>                      {
>                          0x0C
>                      }
>                  Return (EDSM (Arg0, Arg1, Arg2, Arg3, Local0))
>              }
>          }
> 
> Putting it on a root port will let the EDSM unused.

Thanks for the example. Would it be correct to say so that EDSM is part of
the coldplug and so could be left for another series, so out of scope for
hotpluging?


Cheers,
Gustavo


^ permalink raw reply	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2025-05-27 19:35 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-14 17:00 [PATCH 00/22] ACPI PCI Hotplug support on ARM Eric Auger
2025-05-14 17:00 ` [PATCH 01/22] hw/i386/acpi-build: Make aml_pci_device_dsm() static Eric Auger
2025-05-20 12:30   ` Gustavo Romero
2025-05-25 15:29   ` Philippe Mathieu-Daudé
2025-05-14 17:00 ` [PATCH 02/22] hw/arm/virt: Introduce machine state acpi pcihp flags and props Eric Auger
2025-05-14 17:00 ` [PATCH 03/22] hw/acpi: Rename and move build_x86_acpi_pci_hotplug to pcihp Eric Auger
2025-05-20 12:31   ` Gustavo Romero
2025-05-14 17:00 ` [PATCH 04/22] hw/pci-host/gpex-acpi: Add native_pci_hotplug arg to acpi_dsdt_add_pci_osc Eric Auger
2025-05-14 17:00 ` [PATCH 05/22] hw/pci-host/gpex-acpi: Split host bridge OSC and DSM generation Eric Auger
2025-05-14 17:00 ` [PATCH 06/22] hw/pci-host/gpex-acpi: Propagate hotplug type info from virt machine downto gpex Eric Auger
2025-05-14 17:00 ` [PATCH 07/22] hw/i386/acpi-build: Turn build_q35_osc_method into a generic method Eric Auger
2025-05-20 12:59   ` Gustavo Romero
2025-05-14 17:00 ` [PATCH 08/22] hw/pci-host/gpex-acpi: Use build_pci_host_bridge_osc_method Eric Auger
2025-05-20 14:09   ` Gustavo Romero
2025-05-21 16:12     ` Eric Auger
2025-05-24 10:54       ` Michael S. Tsirkin
2025-05-26  9:16         ` Eric Auger
2025-05-14 17:00 ` [PATCH 09/22] hw/i386/acpi-build: Introduce build_append_pcihp_resources() helper Eric Auger
2025-05-20 18:57   ` Gustavo Romero
2025-05-14 17:00 ` [PATCH 10/22] hw/acpi/pcihp: Add an AmlRegionSpace arg to build_acpi_pci_hotplug Eric Auger
2025-05-20 18:58   ` Gustavo Romero
2025-05-14 17:00 ` [PATCH 11/22] hw/i386/acpi-build: Move build_append_notification_callback to pcihp Eric Auger
2025-05-20 18:58   ` Gustavo Romero
2025-05-14 17:00 ` [PATCH 12/22] hw/i386/acpi-build: Move build_append_pci_bus_devices/pcihp_slots " Eric Auger
2025-05-20 19:59   ` Gustavo Romero
2025-05-14 17:01 ` [PATCH 13/22] hw/i386/acpi-build: Introduce and use acpi_get_pci_host Eric Auger
2025-05-20 20:00   ` Gustavo Romero
2025-05-26  9:16     ` Eric Auger
2025-05-14 17:01 ` [PATCH 14/22] hw/i386/acpi-build: Move aml_pci_edsm to a generic place Eric Auger
2025-05-21 15:26   ` Gustavo Romero
2025-05-21 15:56     ` Eric Auger
2025-05-21 16:24       ` Gustavo Romero
2025-05-21 20:19         ` Gustavo Romero
2025-05-27  7:18           ` Eric Auger
2025-05-27 19:34             ` Gustavo Romero
2025-05-14 17:01 ` [PATCH 15/22] hw/arm/virt-acpi-build: Modify the DSDT ACPI table to enable ACPI PCI hotplug Eric Auger
2025-05-14 17:01 ` [PATCH 16/22] hw/acpi/ged: Prepare the device to react to PCI hotplug events Eric Auger
2025-05-25 15:34   ` Philippe Mathieu-Daudé
2025-05-14 17:01 ` [PATCH 17/22] hw/acpi/ged: Call pcihp plug callbacks in hotplug handler implementation Eric Auger
2025-05-14 17:01 ` [PATCH 18/22] hw/acpi/ged: Support migration of AcpiPciHpState Eric Auger
2025-05-14 17:01 ` [PATCH 19/22] hw/core/sysbus: Introduce sysbus_mmio_map_name() helper Eric Auger
2025-05-14 17:01 ` [PATCH 20/22] hw/arm/virt: Let virt support pci hotplug/unplug GED event Eric Auger
2025-05-14 17:01 ` [PATCH 21/22] hw/arm/virt: Plug pcihp hotplug/hotunplug callbacks Eric Auger
2025-05-14 17:01 ` [PATCH 22/22] hw/arm/virt: Use ACPI PCI hotplug by default Eric Auger
2025-05-26  5:55 ` [PATCH 00/22] ACPI PCI Hotplug support on ARM Gustavo Romero
2025-05-26 10:21   ` Eric Auger
2025-05-26 13:56     ` Gustavo Romero

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).