From: patrick Date: Sun, 28 Feb 2021 21:09:44 +0000 (+0000) Subject: Implement IOMMU OFW API for on-SoC/non-PCI devices. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ba30109756df8f4fc4f2cc7acf3d10bf7772b1f0;p=openbsd Implement IOMMU OFW API for on-SoC/non-PCI devices. ok kettenis@ --- diff --git a/sys/dev/ofw/ofw_misc.c b/sys/dev/ofw/ofw_misc.c index 4c89f6d6d3f..22d8d606506 100644 --- a/sys/dev/ofw/ofw_misc.c +++ b/sys/dev/ofw/ofw_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofw_misc.c,v 1.29 2021/02/26 11:28:13 kettenis Exp $ */ +/* $OpenBSD: ofw_misc.c,v 1.30 2021/02/28 21:09:44 patrick Exp $ */ /* * Copyright (c) 2017 Mark Kettenis * @@ -871,6 +871,49 @@ iommu_device_do_map(uint32_t phandle, uint32_t *cells, bus_dma_tag_t dmat) return dmat; } +bus_dma_tag_t +iommu_device_map(int node, bus_dma_tag_t dmat) +{ + uint32_t sid = 0; + uint32_t phandle = 0; + uint32_t *cell; + uint32_t *map; + int len, icells, ncells; + + len = OF_getproplen(node, "iommus"); + if (len <= 0) + return dmat; + + map = malloc(len, M_TEMP, M_WAITOK); + OF_getpropintarray(node, "iommus", map, len); + + cell = map; + ncells = len / sizeof(uint32_t); + while (ncells > 1) { + node = OF_getnodebyphandle(cell[0]); + if (node == 0) + goto out; + + icells = OF_getpropint(node, "#iommu-cells", 1); + if (ncells < icells + 1) + goto out; + + KASSERT(icells == 1); + + phandle = cell[0]; + sid = cell[1]; + break; + + cell += (1 + icells); + ncells -= (1 + icells); + } + +out: + free(map, M_TEMP, len); + + return iommu_device_do_map(phandle, &sid, dmat); +} + bus_dma_tag_t iommu_device_map_pci(int node, uint32_t rid, bus_dma_tag_t dmat) { diff --git a/sys/dev/ofw/ofw_misc.h b/sys/dev/ofw/ofw_misc.h index a0cc4cbbba9..2b8659de7b4 100644 --- a/sys/dev/ofw/ofw_misc.h +++ b/sys/dev/ofw/ofw_misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ofw_misc.h,v 1.18 2021/02/25 22:14:54 kettenis Exp $ */ +/* $OpenBSD: ofw_misc.h,v 1.19 2021/02/28 21:09:44 patrick Exp $ */ /* * Copyright (c) 2017 Mark Kettenis * @@ -245,6 +245,7 @@ struct iommu_device { }; void iommu_device_register(struct iommu_device *); +bus_dma_tag_t iommu_device_map(int, bus_dma_tag_t); bus_dma_tag_t iommu_device_map_pci(int, uint32_t, bus_dma_tag_t); #endif /* _DEV_OFW_MISC_H_ */