Add iommu_domain constructor and destructor.
Reviewed by: kib Sponsored by: DARPA/AFRL Differential Revision: https://reviews.freebsd.org/D25956
This commit is contained in:
parent
e70d59c0dd
commit
16696f6057
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=363946
@ -1063,3 +1063,23 @@ bus_dma_iommu_load_ident(bus_dma_tag_t dmat, bus_dmamap_t map1,
|
||||
free(ma, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
iommu_domain_init(struct iommu_unit *unit, struct iommu_domain *domain,
|
||||
const struct iommu_domain_map_ops *ops)
|
||||
{
|
||||
|
||||
domain->ops = ops;
|
||||
domain->iommu = unit;
|
||||
|
||||
RB_INIT(&domain->rb_root);
|
||||
TAILQ_INIT(&domain->unload_entries);
|
||||
mtx_init(&domain->lock, "iodom", NULL, MTX_DEF);
|
||||
}
|
||||
|
||||
void
|
||||
iommu_domain_fini(struct iommu_domain *domain)
|
||||
{
|
||||
|
||||
mtx_destroy(&domain->lock);
|
||||
}
|
||||
|
@ -223,6 +223,9 @@ int iommu_gas_reserve_region(struct iommu_domain *domain, iommu_gaddr_t start,
|
||||
|
||||
void iommu_set_buswide_ctx(struct iommu_unit *unit, u_int busno);
|
||||
bool iommu_is_buswide_ctx(struct iommu_unit *unit, u_int busno);
|
||||
void iommu_domain_init(struct iommu_unit *unit, struct iommu_domain *domain,
|
||||
const struct iommu_domain_map_ops *ops);
|
||||
void iommu_domain_fini(struct iommu_domain *domain);
|
||||
|
||||
bool bus_dma_iommu_set_buswide(device_t dev);
|
||||
int bus_dma_iommu_load_ident(bus_dma_tag_t dmat, bus_dmamap_t map,
|
||||
|
@ -322,6 +322,7 @@ static struct dmar_domain *
|
||||
dmar_domain_alloc(struct dmar_unit *dmar, bool id_mapped)
|
||||
{
|
||||
struct iommu_domain *iodom;
|
||||
struct iommu_unit *unit;
|
||||
struct dmar_domain *domain;
|
||||
int error, id, mgaw;
|
||||
|
||||
@ -330,16 +331,14 @@ dmar_domain_alloc(struct dmar_unit *dmar, bool id_mapped)
|
||||
return (NULL);
|
||||
domain = malloc(sizeof(*domain), M_DMAR_DOMAIN, M_WAITOK | M_ZERO);
|
||||
iodom = DOM2IODOM(domain);
|
||||
unit = DMAR2IOMMU(dmar);
|
||||
domain->domain = id;
|
||||
LIST_INIT(&domain->contexts);
|
||||
RB_INIT(&domain->iodom.rb_root);
|
||||
TAILQ_INIT(&domain->iodom.unload_entries);
|
||||
TASK_INIT(&domain->iodom.unload_task, 0, dmar_domain_unload_task,
|
||||
domain);
|
||||
mtx_init(&domain->iodom.lock, "dmardom", NULL, MTX_DEF);
|
||||
iommu_domain_init(unit, iodom, &dmar_domain_map_ops);
|
||||
|
||||
domain->dmar = dmar;
|
||||
domain->iodom.iommu = &dmar->iommu;
|
||||
domain_pgtbl_init(domain);
|
||||
|
||||
/*
|
||||
* For now, use the maximal usable physical address of the
|
||||
@ -430,8 +429,11 @@ dmar_ctx_unlink(struct dmar_ctx *ctx)
|
||||
static void
|
||||
dmar_domain_destroy(struct dmar_domain *domain)
|
||||
{
|
||||
struct iommu_domain *iodom;
|
||||
struct dmar_unit *dmar;
|
||||
|
||||
iodom = DOM2IODOM(domain);
|
||||
|
||||
KASSERT(TAILQ_EMPTY(&domain->iodom.unload_entries),
|
||||
("unfinished unloads %p", domain));
|
||||
KASSERT(LIST_EMPTY(&domain->contexts),
|
||||
@ -442,7 +444,7 @@ dmar_domain_destroy(struct dmar_domain *domain)
|
||||
("destroying dom %p with refs %d", domain, domain->refs));
|
||||
if ((domain->iodom.flags & IOMMU_DOMAIN_GAS_INITED) != 0) {
|
||||
DMAR_DOMAIN_LOCK(domain);
|
||||
iommu_gas_fini_domain(DOM2IODOM(domain));
|
||||
iommu_gas_fini_domain(iodom);
|
||||
DMAR_DOMAIN_UNLOCK(domain);
|
||||
}
|
||||
if ((domain->iodom.flags & IOMMU_DOMAIN_PGTBL_INITED) != 0) {
|
||||
@ -450,7 +452,7 @@ dmar_domain_destroy(struct dmar_domain *domain)
|
||||
DMAR_DOMAIN_PGLOCK(domain);
|
||||
domain_free_pgtbl(domain);
|
||||
}
|
||||
mtx_destroy(&domain->iodom.lock);
|
||||
iommu_domain_fini(iodom);
|
||||
dmar = DOM2DMAR(domain);
|
||||
free_unr(dmar->domids, domain->domain);
|
||||
free(domain, M_DMAR_DOMAIN);
|
||||
|
@ -264,7 +264,7 @@ void domain_flush_iotlb_sync(struct dmar_domain *domain, iommu_gaddr_t base,
|
||||
iommu_gaddr_t size);
|
||||
int domain_alloc_pgtbl(struct dmar_domain *domain);
|
||||
void domain_free_pgtbl(struct dmar_domain *domain);
|
||||
void domain_pgtbl_init(struct dmar_domain *domain);
|
||||
extern const struct iommu_domain_map_ops dmar_domain_map_ops;
|
||||
|
||||
int dmar_dev_depth(device_t child);
|
||||
void dmar_dev_path(device_t child, int *busno, void *path1, int depth);
|
||||
|
@ -813,16 +813,7 @@ domain_flush_iotlb_sync(struct dmar_domain *domain, iommu_gaddr_t base,
|
||||
DMAR_UNLOCK(unit);
|
||||
}
|
||||
|
||||
static const struct iommu_domain_map_ops dmar_domain_map_ops = {
|
||||
const struct iommu_domain_map_ops dmar_domain_map_ops = {
|
||||
.map = domain_map_buf,
|
||||
.unmap = domain_unmap_buf,
|
||||
};
|
||||
|
||||
void
|
||||
domain_pgtbl_init(struct dmar_domain *domain)
|
||||
{
|
||||
struct iommu_domain *iodom;
|
||||
|
||||
iodom = DOM2IODOM(domain);
|
||||
iodom->ops = &dmar_domain_map_ops;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user