On Mon, Sep 17, 2018 at 11:02:59PM +0800, Zihan Yang wrote:
To support multiple pci domains of pxb-pcie device in qemu, we need to setup mcfg range in seabios. We use [0x80000000, 0xb0000000) to hold new domain mcfg table for now, and we need to retrieve the desired mcfg size of each pxb-pcie from a hidden bar because they may not need the whole 256 busses, which also enables us to support more domains within a limited range (768MB)
At a highlevel, this looks okay to me. I'd like to see additional reviews from others more familiar with the QEMU PCI code, though.
Is the plan to do the same thing for OVMF?
-Kevin
Signed-off-by: Zihan Yang whois.zihan.yang@gmail.com
src/fw/dev-q35.h | 7 +++++++ src/fw/pciinit.c | 32 ++++++++++++++++++++++++++++++++ src/hw/pci_ids.h | 1 + 3 files changed, 40 insertions(+)
diff --git a/src/fw/dev-q35.h b/src/fw/dev-q35.h index 201825d..229cd81 100644 --- a/src/fw/dev-q35.h +++ b/src/fw/dev-q35.h @@ -49,4 +49,11 @@ #define ICH9_APM_ACPI_ENABLE 0x2 #define ICH9_APM_ACPI_DISABLE 0x3
+#define PXB_PCIE_HOST_BRIDGE_MCFG_BAR 0x50 /* 64bit register */ +#define PXB_PCIE_HOST_BRIDGE_MCFG_SIZE 0x58 /* 32bit register */ +#define PXB_PCIE_HOST_BRIDGE_ENABLE Q35_HOST_BRIDGE_PCIEXBAREN +/* pxb-pcie can use [0x80000000, 0xb0000000), be careful not to overflow */ +#define PXB_PCIE_HOST_BRIDGE_MCFG_SIZE_ADDR 0x80000000 +#define PXB_PCIE_HOST_BRIDGE_MCFG_SIZE_ADDR_UPPER Q35_HOST_BRIDGE_PCIEXBAR_ADDR
#endif // dev-q35.h diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index c0634bc..e0ac22c 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -51,6 +51,7 @@ u64 pcimem_end = BUILD_PCIMEM_END; u64 pcimem64_start = BUILD_PCIMEM64_START; u64 pcimem64_end = BUILD_PCIMEM64_END; u64 pci_io_low_end = 0xa000; +u64 pxb_pcie_mcfg_base = PXB_PCIE_HOST_BRIDGE_MCFG_SIZE_ADDR;
struct pci_region_entry { struct pci_device *dev; @@ -507,11 +508,42 @@ static void mch_mem_addr_setup(struct pci_device *dev, void *arg) pci_io_low_end = acpi_pm_base; }
+static void pxb_pcie_mem_addr_setup(struct pci_device *dev, void *arg) +{
- u64 mcfg_base;
- u32 mcfg_size = pci_config_readl(dev->bdf, PXB_PCIE_HOST_BRIDGE_MCFG_SIZE);
- /* 0 means this pxb-pcie still resides in pci domain 0 */
- if (mcfg_size == 0)
return;
- if (pxb_pcie_mcfg_base + mcfg_size >
PXB_PCIE_HOST_BRIDGE_MCFG_SIZE_ADDR_UPPER) {
dprintf(1, "PCI: Not enough space to hold new pci domains\n");
return;
- }
- mcfg_base = pxb_pcie_mcfg_base;
- pxb_pcie_mcfg_base += mcfg_size;
- /* First clear old mmio, taken care of by QEMU */
- pci_config_writel(dev->bdf, PXB_PCIE_HOST_BRIDGE_MCFG_BAR, 0);
- /* Update MCFG base */
- pci_config_writel(dev->bdf, PXB_PCIE_HOST_BRIDGE_MCFG_BAR + 4,
mcfg_base >> 32);
- pci_config_writel(dev->bdf, PXB_PCIE_HOST_BRIDGE_MCFG_BAR,
(mcfg_base & 0xffffffff) | PXB_PCIE_HOST_BRIDGE_ENABLE);
- e820_add(mcfg_base, mcfg_size, E820_RESERVED);
+}
static const struct pci_device_id pci_platform_tbl[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, i440fx_mem_addr_setup), PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q35_MCH, mch_mem_addr_setup),
- PCI_DEVICE(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_PXB_HOST,
PCI_DEVICE_ENDpxb_pcie_mem_addr_setup),
};
diff --git a/src/hw/pci_ids.h b/src/hw/pci_ids.h index 1096461..b495920 100644 --- a/src/hw/pci_ids.h +++ b/src/hw/pci_ids.h @@ -2266,6 +2266,7 @@ #define PCI_VENDOR_ID_REDHAT 0x1b36 #define PCI_DEVICE_ID_REDHAT_ROOT_PORT 0x000C #define PCI_DEVICE_ID_REDHAT_BRIDGE 0x0001 +#define PCI_DEVICE_ID_REDHAT_PXB_HOST 0x000B
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
2.7.4
SeaBIOS mailing list SeaBIOS@seabios.org https://mail.coreboot.org/mailman/listinfo/seabios