@@ -947,60 +947,18 @@ static inline void versal_create_and_connect_gic(Versal *s,
947947 }
948948}
949949
950- static void versal_create_pcie (Versal * s , const struct VersalPcieMap * map )
950+ /*
951+ * Create the PCIe FDT node before the GIC/ITS FDT node is added. FDT
952+ * subnodes are prepended, so creating the PCIe node early keeps GIC/ITS
953+ * before PCIe in the final DTB. Some guests rely on this order so the
954+ * MSI controller is registered before PCIe devices are attached.
955+ */
956+ static void versal_create_pcie_fdt (Versal * s , const struct VersalPcieMap * map )
951957{
952- DeviceState * dev ;
953- PCIHostState * pci ;
954- MemoryRegion * ecam_alias ;
955- MemoryRegion * ecam_reg ;
956- MemoryRegion * mmio_alias ;
957- MemoryRegion * mmio_high_alias ;
958- MemoryRegion * mmio_reg ;
959- MemoryRegion * ioport_reg ;
960958 g_autofree char * node = NULL ;
961959 const char compat [] = "pci-host-ecam-generic" ;
962960 int num_buses ;
963- int i ;
964-
965- dev = qdev_new (TYPE_GPEX_HOST );
966- object_property_add_child (OBJECT (s ), "pcie" , OBJECT (dev ));
967- sysbus_realize_and_unref (SYS_BUS_DEVICE (dev ), & error_fatal );
968-
969- /* Map ECAM space */
970- ecam_alias = g_new0 (MemoryRegion , 1 );
971- ecam_reg = sysbus_mmio_get_region (SYS_BUS_DEVICE (dev ), 0 );
972- memory_region_init_alias (ecam_alias , OBJECT (dev ), "pcie-ecam" ,
973- ecam_reg , 0 , map -> ecam_size );
974- memory_region_add_subregion (& s -> mr_ps , map -> ecam , ecam_alias );
975-
976- /* Map MMIO window */
977- mmio_alias = g_new0 (MemoryRegion , 1 );
978- mmio_reg = sysbus_mmio_get_region (SYS_BUS_DEVICE (dev ), 1 );
979- memory_region_init_alias (mmio_alias , OBJECT (dev ), "pcie-mmio" ,
980- mmio_reg , map -> mmio , map -> mmio_size );
981- memory_region_add_subregion (& s -> mr_ps , map -> mmio , mmio_alias );
982-
983- /* Map high MMIO window */
984- mmio_high_alias = g_new0 (MemoryRegion , 1 );
985- memory_region_init_alias (mmio_high_alias , OBJECT (dev ), "pcie-mmio-high" ,
986- mmio_reg , map -> mmio_high , map -> mmio_high_size );
987- memory_region_add_subregion (& s -> mr_ps , map -> mmio_high , mmio_high_alias );
988-
989- /* Map IO port space */
990- ioport_reg = sysbus_mmio_get_region (SYS_BUS_DEVICE (dev ), 2 );
991- memory_region_add_subregion (& s -> mr_ps , map -> pio , ioport_reg );
992-
993- /* Map IRQs */
994- for (i = 0 ; i < PCI_NUM_PINS ; i ++ ) {
995- versal_sysbus_connect_irq (s , SYS_BUS_DEVICE (dev ), i , map -> irq [i ]);
996- gpex_set_irq_num (GPEX_HOST (dev ), i , map -> irq [i ]);
997- }
998-
999- /* configure root complex */
1000- pci = PCI_HOST_BRIDGE (dev );
1001- pci -> bypass_iommu = true;
1002-
1003- /* FDT generation */
961+ /* FDT generation */
1004962 num_buses = map -> ecam_size / PCIE_MMCFG_SIZE_MIN ;
1005963 node = g_strdup_printf ("/pcie@%" PRIx64 , map -> mmio );
1006964 qemu_fdt_add_subnode (s -> cfg .fdt , node );
@@ -1075,6 +1033,57 @@ static void versal_create_pcie(Versal *s, const struct VersalPcieMap *map)
10751033 compat , sizeof (compat ));
10761034}
10771035
1036+ static void versal_create_pcie (Versal * s , const struct VersalPcieMap * map )
1037+ {
1038+ DeviceState * dev ;
1039+ PCIHostState * pci ;
1040+ MemoryRegion * ecam_alias ;
1041+ MemoryRegion * ecam_reg ;
1042+ MemoryRegion * mmio_alias ;
1043+ MemoryRegion * mmio_high_alias ;
1044+ MemoryRegion * mmio_reg ;
1045+ MemoryRegion * ioport_reg ;
1046+ int i ;
1047+
1048+ dev = qdev_new (TYPE_GPEX_HOST );
1049+ object_property_add_child (OBJECT (s ), "pcie" , OBJECT (dev ));
1050+ sysbus_realize_and_unref (SYS_BUS_DEVICE (dev ), & error_fatal );
1051+
1052+ /* Map ECAM space */
1053+ ecam_alias = g_new0 (MemoryRegion , 1 );
1054+ ecam_reg = sysbus_mmio_get_region (SYS_BUS_DEVICE (dev ), 0 );
1055+ memory_region_init_alias (ecam_alias , OBJECT (dev ), "pcie-ecam" ,
1056+ ecam_reg , 0 , map -> ecam_size );
1057+ memory_region_add_subregion (& s -> mr_ps , map -> ecam , ecam_alias );
1058+
1059+ /* Map MMIO window */
1060+ mmio_alias = g_new0 (MemoryRegion , 1 );
1061+ mmio_reg = sysbus_mmio_get_region (SYS_BUS_DEVICE (dev ), 1 );
1062+ memory_region_init_alias (mmio_alias , OBJECT (dev ), "pcie-mmio" ,
1063+ mmio_reg , map -> mmio , map -> mmio_size );
1064+ memory_region_add_subregion (& s -> mr_ps , map -> mmio , mmio_alias );
1065+
1066+ /* Map high MMIO window */
1067+ mmio_high_alias = g_new0 (MemoryRegion , 1 );
1068+ memory_region_init_alias (mmio_high_alias , OBJECT (dev ), "pcie-mmio-high" ,
1069+ mmio_reg , map -> mmio_high , map -> mmio_high_size );
1070+ memory_region_add_subregion (& s -> mr_ps , map -> mmio_high , mmio_high_alias );
1071+
1072+ /* Map IO port space */
1073+ ioport_reg = sysbus_mmio_get_region (SYS_BUS_DEVICE (dev ), 2 );
1074+ memory_region_add_subregion (& s -> mr_ps , map -> pio , ioport_reg );
1075+
1076+ /* Map IRQs */
1077+ for (i = 0 ; i < PCI_NUM_PINS ; i ++ ) {
1078+ versal_sysbus_connect_irq (s , SYS_BUS_DEVICE (dev ), i , map -> irq [i ]);
1079+ gpex_set_irq_num (GPEX_HOST (dev ), i , map -> irq [i ]);
1080+ }
1081+
1082+ /* configure root complex */
1083+ pci = PCI_HOST_BRIDGE (dev );
1084+ pci -> bypass_iommu = true;
1085+ }
1086+
10781087static DeviceState * versal_create_cpu (Versal * s ,
10791088 const VersalCpuClusterMap * map ,
10801089 DeviceState * qemu_cluster ,
@@ -2244,10 +2253,6 @@ static void versal_realize_common(Versal *s)
22442253 versal_create_smmu (s , & map -> smmu );
22452254 }
22462255
2247- if (map -> pcie .mmio ) {
2248- versal_create_pcie (s , & map -> pcie );
2249- }
2250-
22512256 if (map -> lpd_iou_slcr ) {
22522257 versal_create_lpd_iou_slcr (s , map -> lpd_iou_slcr );
22532258 }
@@ -2289,8 +2294,10 @@ static void versal_realize_common(Versal *s)
22892294static void versal_realize (DeviceState * dev , Error * * errp )
22902295{
22912296 Versal * s = XLNX_VERSAL_BASE (dev );
2292-
2297+ const VersalMap * map = versal_get_map (s );
2298+ versal_create_pcie_fdt (s , & map -> pcie );
22932299 versal_realize_common (s );
2300+ versal_create_pcie (s , & map -> pcie );
22942301 versal_unimp (s );
22952302}
22962303
0 commit comments