qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH 3/6] hw/pci-host: Enable DW PCIe host to send memory transact


From: Jason Chien
Subject: [RFC PATCH 3/6] hw/pci-host: Enable DW PCIe host to send memory transactions over specific mr
Date: Mon, 16 Dec 2024 08:48:54 +0800

Current Designware PCIe host cannot connect to an IOMMU, since it has
registered PCIIOMMUOps.get_address_space() and an IOMMU cannot overwrite
PCIIOMMUOps.get_address_space() without breaking the PCIe translation
rules.

This commit implements designware_pcie_host_set_mem(), which is used to
register PCIIOMMUOps.set_memory_region(), so an IOMMU can designate the
downstream memory region for the PCIe devices.

Signed-off-by: Jason Chien <jason.chien@sifive.com>
---
 hw/pci-host/designware.c         | 18 +++++++++++++++---
 include/hw/pci-host/designware.h |  2 ++
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index c3fc37b904..8afe447562 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -395,7 +395,6 @@ static void designware_pcie_root_realize(PCIDevice *dev, 
Error **errp)
 {
     DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(dev);
     DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
-    MemoryRegion *host_mem = get_system_memory();
     MemoryRegion *address_space = &host->pci.memory;
     PCIBridge *br = PCI_BRIDGE(dev);
     DesignwarePCIEViewport *viewport;
@@ -436,7 +435,7 @@ static void designware_pcie_root_realize(PCIDevice *dev, 
Error **errp)
         viewport->cr[0]   = DESIGNWARE_PCIE_ATU_TYPE_MEM;
 
         source      = &host->pci.address_space_root;
-        destination = host_mem;
+        destination = &host->bridge_mr;
         direction   = "Inbound";
 
         /*
@@ -461,7 +460,7 @@ static void designware_pcie_root_realize(PCIDevice *dev, 
Error **errp)
 
         destination = &host->pci.memory;
         direction   = "Outbound";
-        source      = host_mem;
+        source      = get_system_memory();
 
         /*
          * Configure MemoryRegion implementing CPU -> PCI memory
@@ -666,8 +665,16 @@ static AddressSpace *designware_pcie_host_set_iommu(PCIBus 
*bus, void *opaque,
     return &s->pci.address_space;
 }
 
+void designware_pcie_host_set_mem(void *opaque, MemoryRegion *mr)
+{
+    DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(opaque);
+
+    memory_region_add_subregion_overlap(&s->bridge_mr, 0, mr, INT32_MAX);
+}
+
 static const PCIIOMMUOps designware_iommu_ops = {
     .get_address_space = designware_pcie_host_set_iommu,
+    .set_memory_region = designware_pcie_host_set_mem,
 };
 
 static void designware_pcie_host_realize(DeviceState *dev, Error **errp)
@@ -703,6 +710,11 @@ static void designware_pcie_host_realize(DeviceState *dev, 
Error **errp)
                                      TYPE_PCIE_BUS);
     pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
 
+    memory_region_init(&s->bridge_mr, OBJECT(s),
+                       "pcie-bus-bridge-memory", UINT64_MAX);
+    memory_region_add_subregion(&s->bridge_mr, 0x0, get_system_memory());
+    address_space_init(&s->bridge_as, &s->bridge_mr, "pcie-bus-bridge-space");
+
     memory_region_init(&s->pci.address_space_root,
                        OBJECT(s),
                        "pcie-bus-address-space-root",
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
index c484e377a8..9562a4ff96 100644
--- a/include/hw/pci-host/designware.h
+++ b/include/hw/pci-host/designware.h
@@ -89,6 +89,8 @@ struct DesignwarePCIEHost {
     } pci;
 
     MemoryRegion mmio;
+    AddressSpace bridge_as;
+    MemoryRegion bridge_mr;
 };
 
 #endif /* DESIGNWARE_H */
-- 
2.43.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]