@@ -747,6 +747,22 @@ static int __init write_properties(struct domain *d, struct kernel_info *kinfo,
return res;
}
+ if ( is_pci_passthrough_enabled() && dt_device_type_is_equal(node, "pci") )
+ {
+ if ( !dt_find_property(node, "linux,pci-domain", NULL) )
+ {
+ uint16_t segment;
+
+ res = pci_get_host_bridge_segment(node, &segment);
+ if ( res < 0 )
+ return res;
+
+ res = fdt_property_cell(kinfo->fdt, "linux,pci-domain", segment);
+ if ( res )
+ return res;
+ }
+ }
+
/*
* Override the property "status" to disable the device when it's
* marked for passthrough.
@@ -255,6 +255,27 @@ struct pci_host_bridge *pci_find_host_bridge(uint16_t segment, uint8_t bus)
return NULL;
}
+
+/*
+ * This function will lookup an hostbridge based on config space address.
+ */
+int pci_get_host_bridge_segment(const struct dt_device_node *node,
+ uint16_t *segment)
+{
+ struct pci_host_bridge *bridge;
+
+ list_for_each_entry( bridge, &pci_host_bridges, node )
+ {
+ if ( bridge->dt_node != node )
+ continue;
+
+ *segment = bridge->segment;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
/*
* Local variables:
* mode: C
@@ -90,6 +90,8 @@ int pci_generic_config_write(struct pci_host_bridge *bridge, pci_sbdf_t sbdf,
void __iomem *pci_ecam_map_bus(struct pci_host_bridge *bridge,
pci_sbdf_t sbdf, uint32_t where);
struct pci_host_bridge *pci_find_host_bridge(uint16_t segment, uint8_t bus);
+int pci_get_host_bridge_segment(const struct dt_device_node *node,
+ uint16_t *segment);
static always_inline bool is_pci_passthrough_enabled(void)
{
@@ -104,5 +106,12 @@ static always_inline bool is_pci_passthrough_enabled(void)
return false;
}
+static inline int pci_get_host_bridge_segment(const struct dt_device_node *node,
+ uint16_t *segment)
+{
+ ASSERT_UNREACHABLE();
+ return -EINVAL;
+}
+
#endif /*!CONFIG_HAS_PCI*/
#endif /* __ARM_PCI_H__ */