pcihp: make bridge describe itself using AcpiDevAmlIfClass:build_dev_aml

simplify build_append_pci_bus_devices() a bit by handling bridge
specific logic in bridge dedicated AcpiDevAmlIfClass::build_dev_aml
callback.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20230112140312.3096331-30-imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Igor Mammedov 2023-01-12 15:03:01 +01:00 committed by Michael S. Tsirkin
parent d78644c781
commit 6c36ec46b0
8 changed files with 70 additions and 16 deletions

View File

@ -39,6 +39,10 @@ config ACPI_PCIHP
bool bool
depends on ACPI depends on ACPI
config ACPI_PCI_BRIDGE
bool
depends on ACPI && PCI && ACPI_PCIHP
config ACPI_HMAT config ACPI_HMAT
bool bool
depends on ACPI depends on ACPI

View File

@ -19,6 +19,7 @@ acpi_ss.add(when: 'CONFIG_ACPI_HW_REDUCED', if_true: files('generic_event_device
acpi_ss.add(when: 'CONFIG_ACPI_HMAT', if_true: files('hmat.c')) acpi_ss.add(when: 'CONFIG_ACPI_HMAT', if_true: files('hmat.c'))
acpi_ss.add(when: 'CONFIG_ACPI_APEI', if_true: files('ghes.c'), if_false: files('ghes-stub.c')) acpi_ss.add(when: 'CONFIG_ACPI_APEI', if_true: files('ghes.c'), if_false: files('ghes-stub.c'))
acpi_ss.add(when: 'CONFIG_ACPI_PIIX4', if_true: files('piix4.c')) acpi_ss.add(when: 'CONFIG_ACPI_PIIX4', if_true: files('piix4.c'))
acpi_ss.add(when: 'CONFIG_ACPI_PCI_BRIDGE', if_true: files('pci-bridge.c'))
acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_true: files('pcihp.c')) acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_true: files('pcihp.c'))
acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_false: files('acpi-pci-hotplug-stub.c')) acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_false: files('acpi-pci-hotplug-stub.c'))
acpi_ss.add(when: 'CONFIG_ACPI_VIOT', if_true: files('viot.c')) acpi_ss.add(when: 'CONFIG_ACPI_VIOT', if_true: files('viot.c'))
@ -30,9 +31,10 @@ if have_tpm
acpi_ss.add(files('tpm.c')) acpi_ss.add(files('tpm.c'))
endif endif
softmmu_ss.add(when: 'CONFIG_ACPI', if_false: files('acpi-stub.c', 'aml-build-stub.c', 'ghes-stub.c', 'acpi_interface.c')) softmmu_ss.add(when: 'CONFIG_ACPI', if_false: files('acpi-stub.c', 'aml-build-stub.c', 'ghes-stub.c', 'acpi_interface.c'))
softmmu_ss.add(when: 'CONFIG_ACPI_PCI_BRIDGE', if_false: files('pci-bridge-stub.c'))
softmmu_ss.add_all(when: 'CONFIG_ACPI', if_true: acpi_ss) softmmu_ss.add_all(when: 'CONFIG_ACPI', if_true: acpi_ss)
softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('acpi-stub.c', 'aml-build-stub.c', softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('acpi-stub.c', 'aml-build-stub.c',
'acpi-x86-stub.c', 'ipmi-stub.c', 'ghes-stub.c', 'acpi-x86-stub.c', 'ipmi-stub.c', 'ghes-stub.c',
'acpi-mem-hotplug-stub.c', 'acpi-cpu-hotplug-stub.c', 'acpi-mem-hotplug-stub.c', 'acpi-cpu-hotplug-stub.c',
'acpi-pci-hotplug-stub.c', 'acpi-nvdimm-stub.c', 'acpi-pci-hotplug-stub.c', 'acpi-nvdimm-stub.c',
'cxl-stub.c')) 'cxl-stub.c', 'pci-bridge-stub.c'))

20
hw/acpi/pci-bridge-stub.c Normal file
View File

@ -0,0 +1,20 @@
/*
* QEMU ACPI PCI bridge stub
*
* Copyright (c) 2023 Red Hat, Inc.
*
* Author:
* Igor Mammedov <imammedo@redhat.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "hw/acpi/pci.h"
void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope)
{
}

27
hw/acpi/pci-bridge.c Normal file
View File

@ -0,0 +1,27 @@
/*
* QEMU ACPI PCI bridge
*
* Copyright (c) 2023 Red Hat, Inc.
*
* Author:
* Igor Mammedov <imammedo@redhat.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "hw/acpi/pci.h"
#include "hw/pci/pci_bridge.h"
#include "hw/acpi/pcihp.h"
void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope)
{
PCIBridge *br = PCI_BRIDGE(adev);
if (object_property_find(OBJECT(&br->sec_bus), ACPI_PCIHP_PROP_BSEL)) {
build_append_pci_bus_devices(scope, pci_bridge_get_sec_bus(br));
}
}

View File

@ -58,6 +58,7 @@ config PC_ACPI
select ACPI_X86 select ACPI_X86
select ACPI_CPU_HOTPLUG select ACPI_CPU_HOTPLUG
select ACPI_MEMORY_HOTPLUG select ACPI_MEMORY_HOTPLUG
select ACPI_PCI_BRIDGE
select ACPI_VIOT select ACPI_VIOT
select SMBUS_EEPROM select SMBUS_EEPROM
select PFLASH_CFI01 select PFLASH_CFI01

View File

@ -383,8 +383,7 @@ static void build_append_pcihp_notify_entry(Aml *method, int slot)
aml_append(method, if_ctx); aml_append(method, if_ctx);
} }
static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus, void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
bool pcihp_bridge_en)
{ {
Aml *dev, *notify_method = NULL, *method; Aml *dev, *notify_method = NULL, *method;
QObject *bsel; QObject *bsel;
@ -406,7 +405,6 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
/* ACPI spec: 1.0b: Table 6-2 _ADR Object Bus Types, PCI type */ /* ACPI spec: 1.0b: Table 6-2 _ADR Object Bus Types, PCI type */
int adr = slot << 16 | func; int adr = slot << 16 | func;
bool hotpluggbale_slot = false; bool hotpluggbale_slot = false;
bool bridge_in_acpi = false;
bool cold_plugged_bridge = false; bool cold_plugged_bridge = false;
if (pdev) { if (pdev) {
@ -418,7 +416,6 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
*/ */
cold_plugged_bridge = IS_PCI_BRIDGE(pdev) && cold_plugged_bridge = IS_PCI_BRIDGE(pdev) &&
!DEVICE(pdev)->hotplugged; !DEVICE(pdev)->hotplugged;
bridge_in_acpi = cold_plugged_bridge && pcihp_bridge_en;
hotpluggbale_slot = bsel && dc->hotpluggable && hotpluggbale_slot = bsel && dc->hotpluggable &&
!cold_plugged_bridge; !cold_plugged_bridge;
@ -471,16 +468,6 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
call_dev_aml_func(DEVICE(pdev), dev); call_dev_aml_func(DEVICE(pdev), dev);
if (bridge_in_acpi) {
/*
* device is coldplugged bridge,
* add child device descriptions into its scope
*/
PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
build_append_pci_bus_devices(dev, sec_bus, pcihp_bridge_en);
}
if (hotpluggbale_slot) { if (hotpluggbale_slot) {
aml_append(dev, aml_name_decl("_SUN", aml_int(slot))); aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
/* add _EJ0 to make slot hotpluggable */ /* add _EJ0 to make slot hotpluggable */
@ -1704,7 +1691,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
PCIBus *bus = PCI_HOST_BRIDGE(pci_host)->bus; PCIBus *bus = PCI_HOST_BRIDGE(pci_host)->bus;
Aml *scope = aml_scope("PCI0"); Aml *scope = aml_scope("PCI0");
/* Scan all PCI buses. Generate tables to support hotplug. */ /* Scan all PCI buses. Generate tables to support hotplug. */
build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en); build_append_pci_bus_devices(scope, bus);
aml_append(sb_scope, scope); aml_append(sb_scope, scope);
} }
} }

View File

@ -37,6 +37,7 @@
#include "qemu/range.h" #include "qemu/range.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "hw/acpi/acpi_aml_interface.h" #include "hw/acpi/acpi_aml_interface.h"
#include "hw/acpi/pci.h"
/* PCI bridge subsystem vendor ID helper functions */ /* PCI bridge subsystem vendor ID helper functions */
#define PCI_SSVID_SIZEOF 8 #define PCI_SSVID_SIZEOF 8
@ -468,10 +469,18 @@ int pci_bridge_qemu_reserve_cap_init(PCIDevice *dev, int cap_offset,
return 0; return 0;
} }
static void pci_bridge_class_init(ObjectClass *klass, void *data)
{
AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
adevc->build_dev_aml = build_pci_bridge_aml;
}
static const TypeInfo pci_bridge_type_info = { static const TypeInfo pci_bridge_type_info = {
.name = TYPE_PCI_BRIDGE, .name = TYPE_PCI_BRIDGE,
.parent = TYPE_PCI_DEVICE, .parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIBridge), .instance_size = sizeof(PCIBridge),
.class_init = pci_bridge_class_init,
.abstract = true, .abstract = true,
.interfaces = (InterfaceInfo[]) { .interfaces = (InterfaceInfo[]) {
{ TYPE_ACPI_DEV_AML_IF }, { TYPE_ACPI_DEV_AML_IF },

View File

@ -27,6 +27,7 @@
#define HW_ACPI_PCI_H #define HW_ACPI_PCI_H
#include "hw/acpi/bios-linker-loader.h" #include "hw/acpi/bios-linker-loader.h"
#include "hw/acpi/acpi_aml_interface.h"
typedef struct AcpiMcfgInfo { typedef struct AcpiMcfgInfo {
uint64_t base; uint64_t base;
@ -36,4 +37,7 @@ typedef struct AcpiMcfgInfo {
void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info, void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info,
const char *oem_id, const char *oem_table_id); const char *oem_id, const char *oem_table_id);
Aml *aml_pci_device_dsm(void); 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);
#endif #endif