if (fwspec && of_property_read_bool(np, "ats-supported"))
fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
}
/* * Returns: * 0 on success, an iommu was configured * -ENODEV if the device does not have any IOMMU * -EPROBEDEFER if probing should be tried again * -errno fatal errors
*/ int of_iommu_configure(struct device *dev, struct device_node *master_np, const u32 *id)
{ bool dev_iommu_present; int err;
if (!master_np) return -ENODEV;
/* Serialise to make dev->iommu stable under our potential fwspec */
mutex_lock(&iommu_probe_device_lock); if (dev_iommu_fwspec_get(dev)) {
mutex_unlock(&iommu_probe_device_lock); return 0;
}
dev_iommu_present = dev->iommu;
/* * We don't currently walk up the tree looking for a parent IOMMU. * See the `Notes:' section of * Documentation/devicetree/bindings/iommu/iommu.txt
*/ if (dev_is_pci(dev)) { struct of_pci_iommu_alias_info info = {
.dev = dev,
.np = master_np,
};
/* * If we're not on the iommu_probe_device() path (as indicated by the * initial dev->iommu) then try to simulate it. This should no longer * happen unless of_dma_configure() is being misused outside bus code.
*/ if (!err && dev->bus && !dev_iommu_present)
err = iommu_probe_device(dev);
if (err && err != -EPROBE_DEFER)
dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
/* * IOMMU regions without an associated physical region cannot be * mapped and are simply reservations.
*/ if (phys->start >= phys->end) return IOMMU_RESV_RESERVED;
/* may be IOMMU_RESV_DIRECT_RELAXABLE for certain cases */ if (start == phys->start && end == phys->end) return IOMMU_RESV_DIRECT;
/** * of_iommu_get_resv_regions - reserved region driver helper for device tree * @dev: device for which to get reserved regions * @list: reserved region list * * IOMMU drivers can use this to implement their .get_resv_regions() callback * for memory regions attached to a device tree node. See the reserved-memory * device tree bindings on how to use these: * * Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
*/ void of_iommu_get_resv_regions(struct device *dev, struct list_head *list)
{ #if IS_ENABLED(CONFIG_OF_ADDRESS) struct of_phandle_iterator it; int err;
/* * The "reg" property is optional and can be omitted by reserved-memory regions * that represent reservations in the IOVA space, which are regions that should * not be mapped.
*/ if (of_property_present(it.node, "reg")) {
err = of_address_to_resource(it.node, 0, &phys); if (err < 0) {
dev_err(dev, "failed to parse memory region %pOF: %d\n",
it.node, err); continue;
}
}
maps = of_get_property(it.node, "iommu-addresses", &size); if (!maps) continue;
end = maps + size / sizeof(__be32);
while (maps < end) { struct device_node *np;
u32 phandle;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.