Move the ACPI_PCIHP_PROP_BSEL property to the PCIBus object and update all callers accordingly.
Since the existing logic checks for the existence of the ACPI_PCIHP_PROP_BSEL property to enable the relevant ACPI changes, set the type of the underlying variable to int32_t with a default value of -1 indicating that the property has not been set. Signed-off-by: Mark Cave-Ayland <[email protected]> --- include/hw/pci/pci_bus.h | 2 ++ hw/acpi/pci-bridge.c | 9 ++++++++- hw/acpi/pcihp.c | 32 +++++++++++++++----------------- hw/arm/virt-acpi-build.c | 7 ++++++- hw/i386/acpi-build.c | 7 ++++++- hw/pci/pci.c | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 69 insertions(+), 20 deletions(-) diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index c738446788..186a157dbc 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -56,6 +56,8 @@ struct PCIBus { int *irq_count; Notifier machine_done; + + int32_t acpi_pcihp_bsel_val; }; static inline bool pci_bus_is_cxl(PCIBus *bus) diff --git a/hw/acpi/pci-bridge.c b/hw/acpi/pci-bridge.c index 394a919479..9af939363c 100644 --- a/hw/acpi/pci-bridge.c +++ b/hw/acpi/pci-bridge.c @@ -23,6 +23,8 @@ void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope) if (!DEVICE(br)->hotplugged) { PCIBus *sec_bus = pci_bridge_get_sec_bus(br); + Error *local_err = NULL; + int32_t bsel; build_append_pci_bus_devices(scope, sec_bus); @@ -30,9 +32,14 @@ void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope) * generate hotplug slots descriptors if * bridge has ACPI PCI hotplug attached, */ - if (object_property_find(OBJECT(sec_bus), ACPI_PCIHP_PROP_BSEL)) { + bsel = object_property_get_int(OBJECT(sec_bus), ACPI_PCIHP_PROP_BSEL, + &local_err); + + if (local_err == NULL && bsel >= 0) { build_append_pcihp_slots(scope, sec_bus); } + + error_free(local_err); } } diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index a91f523c93..31822f6310 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -58,8 +58,8 @@ typedef struct AcpiPciHpFind { static int acpi_pcihp_get_bsel(PCIBus *bus) { Error *local_err = NULL; - uint64_t bsel = object_property_get_uint(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, - &local_err); + int32_t bsel = object_property_get_int(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, + &local_err); if (local_err || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) { error_free(local_err); @@ -78,18 +78,14 @@ typedef struct { static void *acpi_set_bsel(PCIBus *bus, void *opaque) { BSELInfo *info = opaque; - unsigned *bus_bsel; DeviceState *br = bus->qbus.parent; bool is_bridge = IS_PCI_BRIDGE(br); /* hotplugged bridges can't be described in ACPI ignore them */ if (qbus_is_hotpluggable(BUS(bus))) { if (!is_bridge || (!br->hotplugged && info->has_bridge_hotplug)) { - bus_bsel = g_malloc(sizeof *bus_bsel); - - *bus_bsel = info->bsel_alloc++; - object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, - bus_bsel, OBJ_PROP_FLAG_READ); + object_property_set_int(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, + info->bsel_alloc++, NULL); } } @@ -730,14 +726,16 @@ bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus) /* 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++; + int32_t bsel_val = qnum_get_int(qobject_to(QNum, bsel)); + + if (bsel_val >= 0) { + 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 */ @@ -848,7 +846,7 @@ void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus) 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)); + int32_t bsel_val = qnum_get_int(qobject_to(QNum, bsel)); qobject_unref(bsel); aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val))); diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 3f285ff6c7..926c21324a 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -1138,6 +1138,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = vms->oem_id, .oem_table_id = vms->oem_table_id }; Aml *pci0_scope; + Error *local_err = NULL; + int32_t bsel; acpi_table_begin(&table, table_data); dsdt = init_aml_allocator(); @@ -1196,9 +1198,12 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) aml_append(pci0_scope, build_pci_bridge_edsm()); build_append_pci_bus_devices(pci0_scope, vms->bus); - if (object_property_find(OBJECT(vms->bus), ACPI_PCIHP_PROP_BSEL)) { + bsel = object_property_get_int(OBJECT(vms->bus), ACPI_PCIHP_PROP_BSEL, + &local_err); + if (local_err == NULL && bsel >= 0) { build_append_pcihp_slots(pci0_scope, vms->bus); } + error_free(local_err); if (vms->acpi_dev) { bool acpi_pcihp; diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 2ee061558c..de196f2f4a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1197,15 +1197,20 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, sb_scope = aml_scope("\\_SB"); { Object *pci_host = acpi_get_i386_pci_host(); + Error *local_err = NULL; + int32_t bsel; if (pci_host) { PCIBus *pbus = PCI_HOST_BRIDGE(pci_host)->bus; Aml *ascope = aml_scope("PCI0"); /* Scan all PCI buses. Generate tables to support hotplug. */ build_append_pci_bus_devices(ascope, pbus); - if (object_property_find(OBJECT(pbus), ACPI_PCIHP_PROP_BSEL)) { + bsel = object_property_get_int(OBJECT(pbus), ACPI_PCIHP_PROP_BSEL, + &local_err); + if (local_err == NULL && bsel >= 0) { build_append_pcihp_slots(ascope, pbus); } + error_free(local_err); aml_append(sb_scope, ascope); } } diff --git a/hw/pci/pci.c b/hw/pci/pci.c index cec065d108..db42b5296a 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "qemu/datadir.h" #include "qemu/units.h" +#include "hw/acpi/pcihp.h" #include "hw/core/irq.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bridge.h" @@ -187,6 +188,8 @@ static void pci_bus_realize(BusState *qbus, Error **errp) bus->machine_done.notify = pcibus_machine_done; qemu_add_machine_init_done_notifier(&bus->machine_done); + bus->acpi_pcihp_bsel_val = -1; + vmstate_register_any(NULL, &vmstate_pcibus, bus); } @@ -283,6 +286,30 @@ static GByteArray *pci_bus_fw_cfg_gen_data(Object *obj, Error **errp) return byte_array; } +static void pci_bus_get_acpi_pcihp_bsel_val(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + PCIBus *bus = PCI_BUS(obj); + int32_t bsel_val = bus->acpi_pcihp_bsel_val; + + visit_type_int32(v, name, &bsel_val, errp); +} + +static void pci_bus_set_acpi_pcihp_bsel_val(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + PCIBus *bus = PCI_BUS(obj); + int32_t bsel_val = bus->acpi_pcihp_bsel_val; + + if (!visit_type_int32(v, name, &bsel_val, errp)) { + return; + } + + bus->acpi_pcihp_bsel_val = bsel_val; +} + static void pci_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); @@ -302,6 +329,11 @@ static void pci_bus_class_init(ObjectClass *klass, const void *data) pbc->numa_node = pcibus_numa_node; fwgc->get_data = pci_bus_fw_cfg_gen_data; + + object_class_property_add(klass, ACPI_PCIHP_PROP_BSEL, "int32", + pci_bus_get_acpi_pcihp_bsel_val, + pci_bus_set_acpi_pcihp_bsel_val, + NULL, NULL); } static const TypeInfo pci_bus_info = { -- 2.43.0
