aboutsummaryrefslogtreecommitdiff
path: root/sys/arm64/iommu/iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arm64/iommu/iommu.c')
-rw-r--r--sys/arm64/iommu/iommu.c52
1 files changed, 21 insertions, 31 deletions
diff --git a/sys/arm64/iommu/iommu.c b/sys/arm64/iommu/iommu.c
index cb2b86c9dc41..5db48b3bc276 100644
--- a/sys/arm64/iommu/iommu.c
+++ b/sys/arm64/iommu/iommu.c
@@ -80,22 +80,21 @@ struct iommu_entry {
static LIST_HEAD(, iommu_entry) iommu_list = LIST_HEAD_INITIALIZER(iommu_list);
static int
-iommu_domain_unmap_buf(struct iommu_domain *iodom, iommu_gaddr_t base,
- iommu_gaddr_t size, int flags)
+iommu_domain_unmap_buf(struct iommu_domain *iodom,
+ struct iommu_map_entry *entry, int flags)
{
struct iommu_unit *iommu;
int error;
iommu = iodom->iommu;
-
- error = IOMMU_UNMAP(iommu->dev, iodom, base, size);
-
+ error = IOMMU_UNMAP(iommu->dev, iodom, entry->start, entry->end -
+ entry->start);
return (error);
}
static int
-iommu_domain_map_buf(struct iommu_domain *iodom, iommu_gaddr_t base,
- iommu_gaddr_t size, vm_page_t *ma, uint64_t eflags, int flags)
+iommu_domain_map_buf(struct iommu_domain *iodom, struct iommu_map_entry *entry,
+ vm_page_t *ma, uint64_t eflags, int flags)
{
struct iommu_unit *iommu;
vm_prot_t prot;
@@ -110,12 +109,10 @@ iommu_domain_map_buf(struct iommu_domain *iodom, iommu_gaddr_t base,
if (eflags & IOMMU_MAP_ENTRY_WRITE)
prot |= VM_PROT_WRITE;
- va = base;
-
+ va = entry->start;
iommu = iodom->iommu;
-
- error = IOMMU_MAP(iommu->dev, iodom, va, ma, size, prot);
-
+ error = IOMMU_MAP(iommu->dev, iodom, va, ma, entry->end -
+ entry->start, prot);
return (error);
}
@@ -172,7 +169,6 @@ iommu_tag_init(struct iommu_domain *iodom, struct bus_dma_tag_iommu *t)
maxaddr = MIN(iodom->end, BUS_SPACE_MAXADDR);
- t->common.ref_count = 0;
t->common.impl = &bus_dma_iommu_impl;
t->common.alignment = 1;
t->common.boundary = 0;
@@ -377,32 +373,19 @@ void
iommu_free_ctx_locked(struct iommu_unit *iommu, struct iommu_ctx *ioctx)
{
struct bus_dma_tag_iommu *tag;
+ int error;
IOMMU_ASSERT_LOCKED(iommu);
tag = ioctx->tag;
IOMMU_CTX_FREE(iommu->dev, ioctx);
+ IOMMU_UNLOCK(iommu);
free(tag, M_IOMMU);
-}
-
-void
-iommu_free_ctx(struct iommu_ctx *ioctx)
-{
- struct iommu_unit *iommu;
- struct iommu_domain *iodom;
- int error;
-
- iodom = ioctx->domain;
- iommu = iodom->iommu;
-
- IOMMU_LOCK(iommu);
- iommu_free_ctx_locked(iommu, ioctx);
- IOMMU_UNLOCK(iommu);
/* Since we have a domain per each ctx, remove the domain too. */
- error = iommu_domain_free(iodom);
+ error = iommu_domain_free(ioctx->domain);
if (error)
device_printf(iommu->dev, "Could not free a domain\n");
}
@@ -428,8 +411,8 @@ iommu_domain_unload(struct iommu_domain *iodom,
TAILQ_FOREACH_SAFE(entry, entries, dmamap_link, entry1) {
KASSERT((entry->flags & IOMMU_MAP_ENTRY_MAP) != 0,
("not mapped entry %p %p", iodom, entry));
- error = iodom->ops->unmap(iodom, entry->start, entry->end -
- entry->start, cansleep ? IOMMU_PGF_WAITOK : 0);
+ error = iodom->ops->unmap(iodom, entry,
+ cansleep ? IOMMU_PGF_WAITOK : 0);
KASSERT(error == 0, ("unmap %p error %d", iodom, error));
TAILQ_REMOVE(entries, entry, dmamap_link);
iommu_domain_free_entry(entry, true);
@@ -455,6 +438,7 @@ iommu_register(struct iommu_unit *iommu)
LIST_INSERT_HEAD(&iommu_list, entry, next);
IOMMU_LIST_UNLOCK();
+ sysctl_ctx_init(&iommu->sysctl_ctx);
iommu_init_busdma(iommu);
return (0);
@@ -475,6 +459,7 @@ iommu_unregister(struct iommu_unit *iommu)
IOMMU_LIST_UNLOCK();
iommu_fini_busdma(iommu);
+ sysctl_ctx_free(&iommu->sysctl_ctx);
mtx_destroy(&iommu->lock);
@@ -503,6 +488,11 @@ iommu_find(device_t dev, bool verbose)
}
void
+iommu_unit_pre_instantiate_ctx(struct iommu_unit *unit)
+{
+}
+
+void
iommu_domain_unload_entry(struct iommu_map_entry *entry, bool free,
bool cansleep __unused)
{