Add ofw_bus_iommu_map() that maps PCI requester ID to an IOMMU

specifier based on "iommu-map" DTS property.

Sponsored by: UKRI
This commit is contained in:
Ruslan Bukin 2022-05-06 16:41:11 +01:00
parent 4d48dd6890
commit 0b6bacc787
2 changed files with 46 additions and 1 deletions

View file

@ -491,6 +491,50 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent,
return (err);
}
int
ofw_bus_iommu_map(phandle_t node, uint16_t pci_rid, phandle_t *iommu_parent,
uint32_t *iommu_rid)
{
pcell_t mask, iommu_base, rid_base, rid_length;
uint32_t masked_rid;
pcell_t map[4];
ssize_t len;
int err, i;
len = OF_getproplen(node, "iommu-map");
if (len <= 0)
return (ENOENT);
if (len > sizeof(map))
return (ENOMEM);
len = OF_getencprop(node, "iommu-map", map, 16);
err = ENOENT;
mask = 0xffffffff;
OF_getencprop(node, "iommu-map-mask", &mask, sizeof(mask));
masked_rid = pci_rid & mask;
for (i = 0; i < len; i += 4) {
rid_base = map[i + 0];
rid_length = map[i + 3];
if (masked_rid < rid_base ||
masked_rid >= (rid_base + rid_length))
continue;
iommu_base = map[i + 2];
if (iommu_parent != NULL)
*iommu_parent = map[i + 1];
if (iommu_rid != NULL)
*iommu_rid = masked_rid - rid_base + iommu_base;
err = 0;
break;
}
return (err);
}
static int
ofw_bus_reg_to_rl_helper(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
struct resource_list *rl, const char *reg_source)

View file

@ -92,8 +92,9 @@ int ofw_bus_lookup_imap(phandle_t, struct ofw_bus_iinfo *, void *, int,
int ofw_bus_search_intrmap(void *, int, void *, int, void *, int, void *,
void *, void *, int, phandle_t *);
/* Routines for processing msi maps */
/* Routines for processing msi and iommu maps. */
int ofw_bus_msimap(phandle_t, uint16_t, phandle_t *, uint32_t *);
int ofw_bus_iommu_map(phandle_t, uint16_t, phandle_t *, uint32_t *);
/* Routines for parsing device-tree data into resource lists. */
int ofw_bus_reg_to_rl(device_t, phandle_t, pcell_t, pcell_t,