From nobody Fri Nov 7 09:10:08 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1537196829204952.8065925125671; Mon, 17 Sep 2018 08:07:09 -0700 (PDT) Received: from localhost ([::1]:36017 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g1v7D-0002QY-OD for importer@patchew.org; Mon, 17 Sep 2018 11:07:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53093) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g1uyg-0004Zl-1A for qemu-devel@nongnu.org; Mon, 17 Sep 2018 10:58:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g1uyY-00078e-Op for qemu-devel@nongnu.org; Mon, 17 Sep 2018 10:58:13 -0400 Received: from mail-pf1-x442.google.com ([2607:f8b0:4864:20::442]:39984) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g1uyW-00075R-F7 for qemu-devel@nongnu.org; Mon, 17 Sep 2018 10:58:10 -0400 Received: by mail-pf1-x442.google.com with SMTP id s13-v6so7686700pfi.7 for ; Mon, 17 Sep 2018 07:58:07 -0700 (PDT) Received: from biggerfish-TM1701.lan (45.78.72.26.16clouds.com. [45.78.72.26]) by smtp.gmail.com with ESMTPSA id 87-v6sm21276632pfn.103.2018.09.17.07.58.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 17 Sep 2018 07:58:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xEy0sx36NyDyeGPDwuQ6IzYCbB3NU1/W1QRHPwTeeDk=; b=lc9XMhtNV+xu+8B3aqsW6hHU503zXBxbZsRNLmpSJtxPs5WPoC2CfkqS/dgc/p1Lvc TH7+ovWsdkHeshFX/0k8klG0JtpwSvjcU48Mo4n6gT3FIf4J8I61TRGkqpkXWJuW1j9y +hGS7tZznzotvCp8cBRj5Z/ogiHC0PJnaxMzq11zZO1Mrvspnsi8I6/5behtkb0sQfgU bd2VQGxlrc520q6ysKKMOBCLkSZ0iKUf98JNOVUgtNtC94YlYUmd5vIVbl9hJbM1D1+F VgGGhVhdtgPYrEGwrxbqk2T7XSqokmf3CZP7i7ElOmZBskWuW7QlwnFQ8GybN7kI/tE7 GZcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xEy0sx36NyDyeGPDwuQ6IzYCbB3NU1/W1QRHPwTeeDk=; b=dFNfPWH4LncVBrO63s//VxdQ4BT9abLsDxNkgh5xLr28QY5hneEGXV8dYGgR5WiscY deiwg69YrF/Hvxf+v5MWvu8vB0nc+dO6MvoovK+6zEPzxv4pp1K5VXFpnt2S5o8L8/jn CAqfWl+ohfQX7GFNKlEhGufvTmGvJdSH1SXE8Rr8vLLIbE6CZAAH7cqH+fcf4gD1+EyI AhBCRqV7ajVBgk3WpDP01mds3edeomtM05BQe4Qk5/LdN/FR504TRiTe3jv8ulKZmeeM Yhd5XaRvlRY7p3FzGMcgYp1K2x0zQIUswIT/3qo1quI7VCdKjoTYKhGOpw9iR3S/oQQu COKw== X-Gm-Message-State: APzg51CE+RQ3BnnI53zzXAPtDSxXVfLpcxtlSr5+TvzCCkoRVlRZy/q1 AVO5onyeg9C7iy4erYbjy1ncHKnLimc= X-Google-Smtp-Source: ANB0VdYWpJy6l3/R2OMV1LN52jCsk3BSWdHT8HN3ruH4Jk2TMWTo3YaFhDSHh8E8vvsOdB4oR/DDnA== X-Received: by 2002:a63:2a0b:: with SMTP id q11-v6mr20902235pgq.36.1537196285527; Mon, 17 Sep 2018 07:58:05 -0700 (PDT) From: Zihan Yang To: qemu-devel@nongnu.org Date: Mon, 17 Sep 2018 22:57:34 +0800 Message-Id: <1537196258-12581-4-git-send-email-whois.zihan.yang@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537196258-12581-1-git-send-email-whois.zihan.yang@gmail.com> References: <1537196258-12581-1-git-send-email-whois.zihan.yang@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::442 Subject: [Qemu-devel] [RFC v5 3/6] acpi-build: allocate mcfg for pxb-pcie host bridges X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eduardo Habkost , Zihan Yang , "Michael S. Tsirkin" , Paolo Bonzini , Igor Mammedov , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Allocate new segment for pxb-pcie host bridges in MCFG table, and reserve corresponding MCFG space for them. This allows user-defined pxb-pcie host bridges to be placed in different pci domain than q35 host. The pci_host_bridges list is changed to be tail list to ensure the q35 host is always the first element when traversing the list, because q35 host is inserted beofre pxb-pcie hosts A few new callbacks are added to PCIBusClass to get domain number and max_bus property of a given PCIBus. Only pxb-pcie with a non-zero domain number will have an item in MCFG table, others will still reside in pci domain 0 under q35 host Signed-off-by: Zihan Yang --- hw/i386/acpi-build.c | 109 +++++++++++++++++++++---= ---- hw/pci-bridge/pci_expander_bridge.c | 51 +++++++++---- hw/pci/pci.c | 30 +++++++- include/hw/pci-bridge/pci_expander_bridge.h | 16 ++++ include/hw/pci/pci.h | 2 + include/hw/pci/pci_bus.h | 2 + include/hw/pci/pci_host.h | 2 +- 7 files changed, 167 insertions(+), 45 deletions(-) create mode 100644 include/hw/pci-bridge/pci_expander_bridge.h diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index e1ee8ae..9b49b0e 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -55,6 +55,7 @@ #include "hw/i386/ich9.h" #include "hw/pci/pci_bus.h" #include "hw/pci-host/q35.h" +#include "hw/pci-bridge/pci_expander_bridge.h" #include "hw/i386/x86-iommu.h" =20 #include "hw/acpi/aml-build.h" @@ -89,6 +90,10 @@ typedef struct AcpiMcfgInfo { uint64_t mcfg_base; uint32_t mcfg_size; + uint32_t domain_nr; + uint8_t start_bus; + uint8_t end_bus; + QTAILQ_ENTRY(AcpiMcfgInfo) next; } AcpiMcfgInfo; =20 typedef struct AcpiPmInfo { @@ -119,6 +124,9 @@ typedef struct AcpiBuildPciBusHotplugState { bool pcihp_bridge_en; } AcpiBuildPciBusHotplugState; =20 +static QTAILQ_HEAD(, AcpiMcfgInfo) mcfg =3D + QTAILQ_HEAD_INITIALIZER(mcfg); + static void init_common_fadt_data(Object *o, AcpiFadtData *data) { uint32_t io =3D object_property_get_uint(o, ACPI_PM_PROP_PM_IO_BASE, N= ULL); @@ -2427,18 +2435,28 @@ build_srat(GArray *table_data, BIOSLinker *linker, = MachineState *machine) } =20 static void -build_mcfg_q35(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info) +build_mcfg_q35(GArray *table_data, BIOSLinker *linker) { - AcpiTableMcfg *mcfg; + AcpiTableMcfg *mcfg_tbl; const char *sig; - int len =3D sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]); - - mcfg =3D acpi_data_push(table_data, len); - mcfg->allocation[0].address =3D cpu_to_le64(info->mcfg_base); - /* Only a single allocation so no need to play with segments */ - mcfg->allocation[0].pci_segment =3D cpu_to_le16(0); - mcfg->allocation[0].start_bus_number =3D 0; - mcfg->allocation[0].end_bus_number =3D PCIE_MMCFG_BUS(info->mcfg_size = - 1); + int len, count =3D 0; + AcpiMcfgInfo *info; + + QTAILQ_FOREACH(info, &mcfg, next) { + count++; + } + + len =3D sizeof(*mcfg_tbl) + count * sizeof(mcfg_tbl->allocation[0]); + + mcfg_tbl =3D acpi_data_push(table_data, len); + + count =3D 0; + QTAILQ_FOREACH(info, &mcfg, next) { + mcfg_tbl->allocation[count].address =3D cpu_to_le64(info->mcfg_bas= e); + mcfg_tbl->allocation[count].pci_segment =3D cpu_to_le16(info->doma= in_nr); + mcfg_tbl->allocation[count].start_bus_number =3D info->start_bus; + mcfg_tbl->allocation[count++].end_bus_number =3D info->end_bus; + } =20 /* MCFG is used for ECAM which can be enabled or disabled by guest. * To avoid table size changes (which create migration issues), @@ -2446,13 +2464,13 @@ build_mcfg_q35(GArray *table_data, BIOSLinker *link= er, AcpiMcfgInfo *info) * but set the signature to a reserved value in this case. * ACPI spec requires OSPMs to ignore such tables. */ - if (info->mcfg_base =3D=3D PCIE_BASE_ADDR_UNMAPPED) { + if (QTAILQ_FIRST(&mcfg)->mcfg_base =3D=3D PCIE_BASE_ADDR_UNMAPPED) { /* Reserved signature: ignored by OSPM */ sig =3D "QEMU"; } else { sig =3D "MCFG"; } - build_header(linker, table_data, (void *)mcfg, sig, len, 1, NULL, NULL= ); + build_header(linker, table_data, (void *)mcfg_tbl, sig, len, 1, NULL, = NULL); } =20 /* @@ -2606,25 +2624,66 @@ struct AcpiBuildState { MemoryRegion *linker_mr; } AcpiBuildState; =20 -static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) +static inline void cleanup_mcfg(void) +{ + AcpiMcfgInfo *cfg, *tmp; + + QTAILQ_FOREACH_SAFE (cfg, &mcfg, next, tmp) { + QTAILQ_REMOVE(&mcfg, cfg, next); + free(cfg); + } +} + +static bool acpi_get_mcfg(void) { Object *pci_host; QObject *o; + AcpiMcfgInfo *info; + uint8_t bus_nr =3D 0, end_bus =3D 255; + uint32_t domain_nr =3D 0, mcfg_size =3D MCH_HOST_BRIDGE_PCIEXBAR_MAX; + uint64_t mcfg_base =3D MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT; + PCIBus *bus; =20 pci_host =3D acpi_get_i386_pci_host(); g_assert(pci_host); =20 - o =3D object_property_get_qobject(pci_host, PCIE_HOST_MCFG_BASE, NULL); - if (!o) { - return false; + while (pci_host) { + if (object_dynamic_cast(pci_host, TYPE_PXB_PCIE_HOST)) { + /* we are in pxb-pcie, overwrite default value */ + bus =3D PCI_HOST_BRIDGE(pci_host)->bus; + domain_nr =3D pci_bus_domain_num(bus); + if (domain_nr =3D=3D 0) { + pci_host =3D OBJECT(QTAILQ_NEXT(PCI_HOST_BRIDGE(pci_host),= next)); + continue; + } + + o =3D object_property_get_qobject(pci_host, PCIE_HOST_MCFG_BAS= E, NULL); + assert(o); + mcfg_base =3D qnum_get_uint(qobject_to(QNum, o)); + qobject_unref(o); + + o =3D object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZ= E, NULL); + assert(o); + mcfg_size =3D qnum_get_uint(qobject_to(QNum, o)); + qobject_unref(o); + + bus_nr =3D pci_bus_num(bus); + domain_nr =3D pci_bus_domain_num(bus); + end_bus =3D pci_bus_max_bus(bus); + } + + info =3D g_new0(AcpiMcfgInfo, 1); + g_assert(info); + info->domain_nr =3D domain_nr; + info->start_bus =3D bus_nr; + info->end_bus =3D end_bus; + info->mcfg_base =3D mcfg_base; + info->mcfg_size =3D mcfg_size; + + QTAILQ_INSERT_TAIL(&mcfg, info, next); + pci_host =3D OBJECT(QTAILQ_NEXT(PCI_HOST_BRIDGE(pci_host), next)); } - mcfg->mcfg_base =3D qnum_get_uint(qobject_to(QNum, o)); - qobject_unref(o); =20 - o =3D object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL); - assert(o); - mcfg->mcfg_size =3D qnum_get_uint(qobject_to(QNum, o)); - qobject_unref(o); return true; } =20 @@ -2637,7 +2696,6 @@ void acpi_build(AcpiBuildTables *tables, MachineState= *machine) unsigned facs, dsdt, rsdt, fadt; AcpiPmInfo pm; AcpiMiscInfo misc; - AcpiMcfgInfo mcfg; Range pci_hole, pci_hole64; uint8_t *u; size_t aml_len =3D 0; @@ -2718,10 +2776,11 @@ void acpi_build(AcpiBuildTables *tables, MachineSta= te *machine) build_slit(tables_blob, tables->linker); } } - if (acpi_get_mcfg(&mcfg)) { + if (acpi_get_mcfg()) { acpi_add_table(table_offsets, tables_blob); - build_mcfg_q35(tables_blob, tables->linker, &mcfg); + build_mcfg_q35(tables_blob, tables->linker); } + cleanup_mcfg(); if (x86_iommu_get_default()) { IommuType IOMMUType =3D x86_iommu_get_type(); if (IOMMUType =3D=3D TYPE_AMD) { diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expand= er_bridge.c index 20fec50..1e1999d 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -17,6 +17,7 @@ #include "hw/pci/pci_host.h" #include "hw/pci/pcie_host.h" #include "hw/pci/pci_bridge.h" +#include "hw/pci-bridge/pci_expander_bridge.h" #include "qemu/range.h" #include "qemu/error-report.h" #include "sysemu/numa.h" @@ -58,16 +59,6 @@ typedef struct PXBDev { uint8_t max_bus; /* max bus number to use(including this one) */ } PXBDev; =20 -#define TYPE_PXB_PCIE_HOST "pxb-pcie-host" -#define PXB_PCIE_HOST_DEVICE(obj) \ - OBJECT_CHECK(PXBPCIEHost, (obj), TYPE_PXB_PCIE_HOST) - -typedef struct PXBPCIEHost { - /*< private >*/ - PCIExpressHost parent_obj; - /*< public >*/ -} PXBPCIEHost; - static PXBDev *convert_to_pxb(PCIDevice *dev) { return pci_bus_is_express(pci_get_bus(dev)) @@ -85,11 +76,17 @@ static int pxb_bus_num(PCIBus *bus) return pxb->bus_nr; } =20 -static int pxb_domain_num(PCIBus *bus) +static int pxb_max_bus(PCIBus *bus) +{ + PXBDev *pxb =3D convert_to_pxb(bus->parent_dev); + + return pxb->max_bus; +} + +static uint32_t pxb_domain_num(PCIBus *bus) { PXBDev *pxb =3D convert_to_pxb(bus->parent_dev); =20 - /* for pxb, this should always be zero */ return pxb->domain_nr; } =20 @@ -110,8 +107,10 @@ static void pxb_bus_class_init(ObjectClass *class, voi= d *data) PCIBusClass *pbc =3D PCI_BUS_CLASS(class); =20 pbc->bus_num =3D pxb_bus_num; + pbc->max_bus =3D pxb_max_bus; pbc->is_root =3D pxb_is_root; pbc->numa_node =3D pxb_bus_numa_node; + pbc->domain_num =3D pxb_domain_num; } =20 static const TypeInfo pxb_bus_info =3D { @@ -174,7 +173,17 @@ static void pxb_pcie_host_get_mmcfg_base(Object *obj, = Visitor *v, const char *na { PCIExpressHost *e =3D PCIE_HOST_BRIDGE(obj); =20 - visit_type_uint64(v, name, &e->size, errp); + visit_type_uint64(v, name, &e->base_addr, errp); +} + +static void pxb_pcie_host_set_mmcfg_base(Object *obj, Visitor *v, const ch= ar *name, + void *opaque, Error **errp) +{ + PXBPCIEHost *host =3D PXB_PCIE_HOST_DEVICE(obj); + uint64_t value; + + visit_type_uint64(v, name, &value, errp); + host->parent_obj.base_addr =3D value; } =20 static void pxb_pcie_host_get_mmcfg_size(Object *obj, Visitor *v, const ch= ar *name, @@ -185,6 +194,16 @@ static void pxb_pcie_host_get_mmcfg_size(Object *obj, = Visitor *v, const char *na visit_type_uint64(v, name, &e->size, errp); } =20 +static void pxb_pcie_host_set_mmcfg_size(Object *obj, Visitor *v, const ch= ar *name, + void *opaque, Error **errp) +{ + PXBPCIEHost *host =3D PXB_PCIE_HOST_DEVICE(obj); + uint32_t value; + + visit_type_uint32(v, name, &value, errp); + host->parent_obj.size =3D value; +} + static void pxb_pcie_host_initfn(Object *obj) { PCIHostState *phb =3D PCI_HOST_BRIDGE(obj); @@ -196,11 +215,13 @@ static void pxb_pcie_host_initfn(Object *obj) =20 object_property_add(obj, PCIE_HOST_MCFG_BASE, "uint64", pxb_pcie_host_get_mmcfg_base, - NULL, NULL, NULL, NULL); + pxb_pcie_host_set_mmcfg_base, + NULL, NULL, NULL); =20 object_property_add(obj, PCIE_HOST_MCFG_SIZE, "uint64", pxb_pcie_host_get_mmcfg_size, - NULL, NULL, NULL, NULL); + pxb_pcie_host_set_mmcfg_size, + NULL, NULL, NULL); } =20 static void pxb_host_class_init(ObjectClass *class, void *data) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 80bc459..fe69672 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -142,6 +142,15 @@ static int pcibus_num(PCIBus *bus) return bus->parent_dev->config[PCI_SECONDARY_BUS]; } =20 +/* return 0 unless user overwrite this callback */ +static uint32_t pcibus_domain_num(PCIBus *bus) { + return 0; +} + +static int pcibus_max_bus(PCIBus *bus) { + return 255; +} + static uint16_t pcibus_numa_node(PCIBus *bus) { return NUMA_NODE_UNASSIGNED; @@ -162,6 +171,8 @@ static void pci_bus_class_init(ObjectClass *klass, void= *data) pbc->is_root =3D pcibus_is_root; pbc->bus_num =3D pcibus_num; pbc->numa_node =3D pcibus_numa_node; + pbc->domain_num =3D pcibus_domain_num; + pbc->max_bus =3D pcibus_max_bus; } =20 static const TypeInfo pci_bus_info =3D { @@ -196,7 +207,8 @@ static void pci_del_option_rom(PCIDevice *pdev); static uint16_t pci_default_sub_vendor_id =3D PCI_SUBVENDOR_ID_REDHAT_QUMR= ANET; static uint16_t pci_default_sub_device_id =3D PCI_SUBDEVICE_ID_QEMU; =20 -static QLIST_HEAD(, PCIHostState) pci_host_bridges; +static QTAILQ_HEAD(, PCIHostState) pci_host_bridges =3D + QTAILQ_HEAD_INITIALIZER(pci_host_bridges); =20 int pci_bar(PCIDevice *d, int reg) { @@ -330,7 +342,7 @@ static void pci_host_bus_register(DeviceState *host) { PCIHostState *host_bridge =3D PCI_HOST_BRIDGE(host); =20 - QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next); + QTAILQ_INSERT_TAIL(&pci_host_bridges, host_bridge, next); } =20 PCIBus *pci_device_root_bus(const PCIDevice *d) @@ -444,6 +456,16 @@ int pci_bus_num(PCIBus *s) return PCI_BUS_GET_CLASS(s)->bus_num(s); } =20 +uint32_t pci_bus_domain_num(PCIBus *s) +{ + return PCI_BUS_GET_CLASS(s)->domain_num(s); +} + +int pci_bus_max_bus(PCIBus *s) +{ + return PCI_BUS_GET_CLASS(s)->max_bus(s); +} + int pci_bus_numa_node(PCIBus *bus) { return PCI_BUS_GET_CLASS(bus)->numa_node(bus); @@ -1798,7 +1820,7 @@ PciInfoList *qmp_query_pci(Error **errp) PciInfoList *info, *head =3D NULL, *cur_item =3D NULL; PCIHostState *host_bridge; =20 - QLIST_FOREACH(host_bridge, &pci_host_bridges, next) { + QTAILQ_FOREACH(host_bridge, &pci_host_bridges, next) { info =3D g_malloc0(sizeof(*info)); info->value =3D qmp_query_pci_bus(host_bridge->bus, pci_bus_num(host_bridge->bus)); @@ -2493,7 +2515,7 @@ int pci_qdev_find_device(const char *id, PCIDevice **= pdev) PCIHostState *host_bridge; int rc =3D -ENODEV; =20 - QLIST_FOREACH(host_bridge, &pci_host_bridges, next) { + QTAILQ_FOREACH(host_bridge, &pci_host_bridges, next) { int tmp =3D pci_qdev_find_recursive(host_bridge->bus, id, pdev); if (!tmp) { rc =3D 0; diff --git a/include/hw/pci-bridge/pci_expander_bridge.h b/include/hw/pci-b= ridge/pci_expander_bridge.h new file mode 100644 index 0000000..e017c62 --- /dev/null +++ b/include/hw/pci-bridge/pci_expander_bridge.h @@ -0,0 +1,16 @@ +#ifndef HW_PCI_EXPANDER_H +#define HW_PCI_EXPANDER_H + +#include "hw/pci/pcie_host.h" + +#define TYPE_PXB_PCIE_HOST "pxb-pcie-host" +#define PXB_PCIE_HOST_DEVICE(obj) \ + OBJECT_CHECK(PXBPCIEHost, (obj), TYPE_PXB_PCIE_HOST) + +typedef struct PXBPCIEHost { + /*< private >*/ + PCIExpressHost parent_obj; + /*< public >*/ +} PXBPCIEHost; + +#endif diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 990d6fc..b127fcf 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -436,6 +436,8 @@ static inline PCIBus *pci_get_bus(const PCIDevice *dev) return PCI_BUS(qdev_get_parent_bus(DEVICE(dev))); } int pci_bus_num(PCIBus *s); +uint32_t pci_bus_domain_num(PCIBus *s); +int pci_bus_max_bus(PCIBus *s); static inline int pci_dev_bus_num(const PCIDevice *dev) { return pci_bus_num(pci_get_bus(dev)); diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index b7da8f5..faad155 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -15,7 +15,9 @@ typedef struct PCIBusClass { =20 bool (*is_root)(PCIBus *bus); int (*bus_num)(PCIBus *bus); + int (*max_bus)(PCIBus *bus); uint16_t (*numa_node)(PCIBus *bus); + uint32_t (*domain_num)(PCIBus *bus); } PCIBusClass; =20 struct PCIBus { diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h index ba31595..a5617cf 100644 --- a/include/hw/pci/pci_host.h +++ b/include/hw/pci/pci_host.h @@ -47,7 +47,7 @@ struct PCIHostState { uint32_t config_reg; PCIBus *bus; =20 - QLIST_ENTRY(PCIHostState) next; + QTAILQ_ENTRY(PCIHostState) next; }; =20 typedef struct PCIHostBridgeClass { --=20 2.7.4