* [PATCH 1/2] hw/pci-host: Designware: Fix inbound iATU no address match behavior
2023-11-15 14:33 [PATCH 0/2] hw/pci-host: Fix Designware no address match behavior Max Hsu
@ 2023-11-15 14:33 ` Max Hsu
2023-11-15 14:33 ` [PATCH 2/2] hw/pci-host: Designware: Add outbound " Max Hsu
1 sibling, 0 replies; 3+ messages in thread
From: Max Hsu @ 2023-11-15 14:33 UTC (permalink / raw)
To: Peter Maydell, Andrey Smirnov
Cc: Frank Chang, qemu-arm, Greentime Hu, qemu-devel, Max Hsu
IMX6DQRM Rev4, in chapter 48.3.9.3, specifies that for inbound iATU
with no address match: 'If there is no match, then the address is
untranslated.'
The current model implementation registers inbound region 0 as
untranslated dummy, intending to serve as a passing medium for
the no-match address behavior using MemoryRegion.
However, a bug exists where the Linux Kernel driver of Designware PCIe
RC is unaware that inbound region 0 is registered for special setup.
During Kernel driver initialization, the driver overwrites the target
address to 0x1111_0000 and later disables all regions, rendering the
untranslated passing medium ineffective.
Consequently, TLP cannot pass iATU, and the transaction is blocked.
To address this issue, we propose "inbound untranslated pass" which is
consistently enabled and distinct from the usage of iATU regions.
We achieve this by introducing a new MemoryRegion with the
lowest priority to prevent conflicts with configured iATU regions.
This fix has been tested with the integration of Designware PCIe RC
along with the e1000e Ethernet card, ensuring proper functioning of
network transmissions and MSI interrupts.
Signed-off-by: Max Hsu <max.hsu@sifive.com>
---
hw/pci-host/designware.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index f477f97847..83dd9b1aaf 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -487,17 +487,28 @@ static void designware_pcie_root_realize(PCIDevice *dev, Error **errp)
}
/*
- * If no inbound iATU windows are configured, HW defaults to
- * letting inbound TLPs to pass in. We emulate that by explicitly
- * configuring first inbound window to cover all of target's
- * address space.
+ * For HW iATU address no match behavior, the TLP should continue with
+ * untranslated address.
*
- * NOTE: This will not work correctly for the case when first
- * configured inbound window is window 0
+ * We emulate this behavior by adding extra MemoryRegions to create a
+ * 1:1 mapping between PCI address space and cpu address space within
+ * the 64-bit range, encompassing both inbound and outbound directions.
+ *
+ * To avoid interfering with the configured iATU regions and potentially
+ * producing incorrect addresses, the two untranslated regions are set
+ * to have the lowest priority.
*/
- viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][0];
- viewport->cr[1] = DESIGNWARE_PCIE_ATU_ENABLE;
- designware_pcie_update_viewport(root, viewport);
+ MemoryRegion *inbound_untranslated = g_new(MemoryRegion, 1);
+
+ memory_region_init_alias(inbound_untranslated, OBJECT(root),
+ "inbound untranslated pass",
+ get_system_memory(), dummy_offset, dummy_size);
+ memory_region_add_subregion_overlap(&host->pci.address_space_root,
+ dummy_offset, inbound_untranslated,
+ INT32_MIN);
+ memory_region_set_size(inbound_untranslated, UINT64_MAX);
+ memory_region_set_address(inbound_untranslated, 0x0ULL);
+ memory_region_set_enabled(inbound_untranslated, true);
memory_region_init_io(&root->msi.iomem, OBJECT(root),
&designware_pci_host_msi_ops,
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 2/2] hw/pci-host: Designware: Add outbound iATU no address match behavior
2023-11-15 14:33 [PATCH 0/2] hw/pci-host: Fix Designware no address match behavior Max Hsu
2023-11-15 14:33 ` [PATCH 1/2] hw/pci-host: Designware: Fix inbound iATU " Max Hsu
@ 2023-11-15 14:33 ` Max Hsu
1 sibling, 0 replies; 3+ messages in thread
From: Max Hsu @ 2023-11-15 14:33 UTC (permalink / raw)
To: Peter Maydell, Andrey Smirnov
Cc: Frank Chang, qemu-arm, Greentime Hu, qemu-devel, Max Hsu
IMX6DQRM Rev4, in chapter 48.3.9.2, specifies for outbound iATU with
no address match: 'If there is no address match, then the address is
untranslated.'
The current model implementation only considers inbound occurrences,
neglecting outbound scenarios.
To address this, we introduce a new MemoryRegion to handle the behavior
of no address match in outbound transactions.
This fix has been tested with the integration of Designware PCIe RC
along with the e1000e Ethernet card, ensuring proper functioning of
network transmissions and MSI interrupts.
Signed-off-by: Max Hsu <max.hsu@sifive.com>
---
hw/pci-host/designware.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index 83dd9b1aaf..d0be8dec68 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -499,6 +499,7 @@ static void designware_pcie_root_realize(PCIDevice *dev, Error **errp)
* to have the lowest priority.
*/
MemoryRegion *inbound_untranslated = g_new(MemoryRegion, 1);
+ MemoryRegion *outbound_untranslated = g_new(MemoryRegion, 1);
memory_region_init_alias(inbound_untranslated, OBJECT(root),
"inbound untranslated pass",
@@ -510,6 +511,16 @@ static void designware_pcie_root_realize(PCIDevice *dev, Error **errp)
memory_region_set_address(inbound_untranslated, 0x0ULL);
memory_region_set_enabled(inbound_untranslated, true);
+ memory_region_init_alias(outbound_untranslated, OBJECT(root),
+ "outbound untranslated pass",
+ &host->pci.memory, dummy_offset, dummy_size);
+ memory_region_add_subregion_overlap(get_system_memory(),
+ dummy_offset, outbound_untranslated,
+ INT32_MIN);
+ memory_region_set_size(outbound_untranslated, UINT64_MAX);
+ memory_region_set_address(outbound_untranslated, 0x0ULL);
+ memory_region_set_enabled(outbound_untranslated, true);
+
memory_region_init_io(&root->msi.iomem, OBJECT(root),
&designware_pci_host_msi_ops,
root, "pcie-msi", 0x4);
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread