The number of iATU ports in the RP emulation is 4.
This value is exported via register at address 0x900
The specification states that the value in the resisetr
is 1 less then the actual number.
the Linux kernel routine dw_pcie_iatu_detect in
drivers/pci/controller/dwc/pcie-designware.c follows the
following protocol, fisrt it reads this register,
and if this value is not 0xFFFFFFFF it write 0xFF
to this registers and reads it back, then it set the number
of region to be 1 the number read plus 1.
Then the kernel code tries to initialize this number of inbound
and outbound entries.
The current code in QEMU just accepts the number given by the kernel
and returns it back without considering the implementation limit (4).
As a result, with the current code the kernel tries to initalizes
256 enties. This patch limits the number the kernel can set to
the value imposed by the implementation.
Signed-off-by: Shlomo Pongratz <shlomop@pliops.com>
---
hw/pci-host/designware.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index f477f97847..4558d552ab 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -340,7 +340,8 @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address,
break;
case DESIGNWARE_PCIE_ATU_VIEWPORT:
- root->atu_viewport = val;
+ root->atu_viewport = val < DESIGNWARE_PCIE_NUM_VIEWPORTS ?
+ val : (DESIGNWARE_PCIE_NUM_VIEWPORTS - 1);
break;
case DESIGNWARE_PCIE_ATU_LOWER_BASE:
--
2.25.1