Lines Matching +full:iommu +full:- +full:base
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
66 #include <dev/iommu/busdma_iommu.h>
67 #include <x86/iommu/amd_reg.h>
68 #include <x86/iommu/x86_iommu.h>
69 #include <x86/iommu/amd_iommu.h>
72 iommu_gaddr_t base, int lvl, int flags, iommu_pte_t *pte,
75 iommu_gaddr_t base, iommu_gaddr_t size, int flags,
84 KASSERT(domain->pgtbl_obj == NULL, in amdiommu_domain_alloc_pgtbl()
87 domain->pgtbl_obj = vm_pager_allocate(OBJT_PHYS, NULL, in amdiommu_domain_alloc_pgtbl()
88 IDX_TO_OFF(pglvl_max_pages(domain->pglvl)), 0, 0, NULL); in amdiommu_domain_alloc_pgtbl()
89 if (bus_get_domain(domain->iodom.iommu->dev, &dom) == 0) in amdiommu_domain_alloc_pgtbl()
90 domain->pgtbl_obj->domain.dr_policy = DOMAINSET_PREF(dom); in amdiommu_domain_alloc_pgtbl()
92 m = iommu_pgalloc(domain->pgtbl_obj, 0, IOMMU_PGF_WAITOK | in amdiommu_domain_alloc_pgtbl()
96 domain->pgtblr = m; in amdiommu_domain_alloc_pgtbl()
98 AMDIOMMU_LOCK(domain->unit); in amdiommu_domain_alloc_pgtbl()
99 domain->iodom.flags |= IOMMU_DOMAIN_PGTBL_INITED; in amdiommu_domain_alloc_pgtbl()
100 AMDIOMMU_UNLOCK(domain->unit); in amdiommu_domain_alloc_pgtbl()
111 obj = domain->pgtbl_obj; in amdiommu_domain_free_pgtbl()
113 KASSERT((domain->iodom.flags & IOMMU_DOMAIN_IDMAP) != 0, in amdiommu_domain_free_pgtbl()
118 domain->pgtbl_obj = NULL; in amdiommu_domain_free_pgtbl()
119 domain->pgtblr = NULL; in amdiommu_domain_free_pgtbl()
131 amdiommu_pgtbl_map_pte(struct amdiommu_domain *domain, iommu_gaddr_t base, in amdiommu_pgtbl_map_pte() argument
139 idx = pglvl_pgtbl_get_pindex(domain->pglvl, base, lvl); in amdiommu_pgtbl_map_pte()
147 pte = iommu_map_pgtbl(domain->pgtbl_obj, idx, flags, sf); in amdiommu_pgtbl_map_pte()
156 m = iommu_pgalloc(domain->pgtbl_obj, idx, flags | in amdiommu_pgtbl_map_pte()
164 ptep = amdiommu_pgtbl_map_pte(domain, base, lvl - 1, in amdiommu_pgtbl_map_pte()
167 KASSERT(m->pindex != 0, in amdiommu_pgtbl_map_pte()
170 iommu_pgfree(domain->pgtbl_obj, m->pindex, in amdiommu_pgtbl_map_pte()
174 ptep->pte = VM_PAGE_TO_PHYS(m) | AMDIOMMU_PTE_IR | in amdiommu_pgtbl_map_pte()
176 ((domain->pglvl - lvl) << AMDIOMMU_PTE_NLVL_SHIFT); in amdiommu_pgtbl_map_pte()
184 pte += pglvl_pgtbl_pte_off(domain->pglvl, base, lvl); in amdiommu_pgtbl_map_pte()
189 amdiommu_map_buf_locked(struct amdiommu_domain *domain, iommu_gaddr_t base, in amdiommu_map_buf_locked() argument
200 base1 = base; in amdiommu_map_buf_locked()
202 idx = -1; in amdiommu_map_buf_locked()
206 for (pi = 0; size > 0; base += IOMMU_PAGE_SIZE, size -= IOMMU_PAGE_SIZE, in amdiommu_map_buf_locked()
210 (uintmax_t)base, (uintmax_t)size, (uintmax_t)IOMMU_PAGE_SIZE)); in amdiommu_map_buf_locked()
211 pte = amdiommu_pgtbl_map_pte(domain, base, domain->pglvl - 1, in amdiommu_map_buf_locked()
218 amdiommu_unmap_buf_locked(domain, base1, base - base1, in amdiommu_map_buf_locked()
223 pte->pte = VM_PAGE_TO_PHYS(ma[pi]) | pflags | AMDIOMMU_PTE_PR; in amdiommu_map_buf_locked()
237 iommu_gaddr_t base, size; in amdiommu_map_buf() local
240 base = entry->start; in amdiommu_map_buf()
241 size = entry->end - entry->start; in amdiommu_map_buf()
249 KASSERT((iodom->flags & IOMMU_DOMAIN_IDMAP) == 0, in amdiommu_map_buf()
251 KASSERT((base & IOMMU_PAGE_MASK) == 0, in amdiommu_map_buf()
252 ("non-aligned base %p %jx %jx", domain, (uintmax_t)base, in amdiommu_map_buf()
255 ("non-aligned size %p %jx %jx", domain, (uintmax_t)base, in amdiommu_map_buf()
257 KASSERT(size > 0, ("zero size %p %jx %jx", domain, (uintmax_t)base, in amdiommu_map_buf()
259 KASSERT(base < iodom->end, in amdiommu_map_buf()
260 ("base too high %p %jx %jx end %jx", domain, (uintmax_t)base, in amdiommu_map_buf()
261 (uintmax_t)size, (uintmax_t)iodom->end)); in amdiommu_map_buf()
262 KASSERT(base + size < iodom->end, in amdiommu_map_buf()
263 ("end too high %p %jx %jx end %jx", domain, (uintmax_t)base, in amdiommu_map_buf()
264 (uintmax_t)size, (uintmax_t)iodom->end)); in amdiommu_map_buf()
265 KASSERT(base + size > base, in amdiommu_map_buf()
266 ("size overflow %p %jx %jx", domain, (uintmax_t)base, in amdiommu_map_buf()
276 error = amdiommu_map_buf_locked(domain, base, size, ma, pflags, in amdiommu_map_buf()
281 * XXXKIB invalidation seems to be needed even for non-valid->valid in amdiommu_map_buf()
284 iommu_qi_invalidate_sync(iodom, base, size, in amdiommu_map_buf()
290 amdiommu_free_pgtbl_pde(struct amdiommu_domain *domain, iommu_gaddr_t base, in amdiommu_free_pgtbl_pde() argument
298 pde = amdiommu_pgtbl_map_pte(domain, base, lvl, flags, &idx, &sf); in amdiommu_free_pgtbl_pde()
299 amdiommu_unmap_clear_pte(domain, base, lvl, flags, pde, &sf, entry, in amdiommu_free_pgtbl_pde()
304 amdiommu_unmap_clear_pte(struct amdiommu_domain *domain, iommu_gaddr_t base, in amdiommu_unmap_clear_pte() argument
310 pte->pte = 0; in amdiommu_unmap_clear_pte()
319 ("lost reference (lvl) on root pg domain %p base %jx lvl %d", in amdiommu_unmap_clear_pte()
320 domain, (uintmax_t)base, lvl)); in amdiommu_unmap_clear_pte()
321 KASSERT(m->pindex != 0, in amdiommu_unmap_clear_pte()
322 ("lost reference (idx) on root pg domain %p base %jx lvl %d", in amdiommu_unmap_clear_pte()
323 domain, (uintmax_t)base, lvl)); in amdiommu_unmap_clear_pte()
324 iommu_pgfree(domain->pgtbl_obj, m->pindex, flags, entry); in amdiommu_unmap_clear_pte()
325 amdiommu_free_pgtbl_pde(domain, base, lvl - 1, flags, entry); in amdiommu_unmap_clear_pte()
329 amdiommu_unmap_buf_locked(struct amdiommu_domain *domain, iommu_gaddr_t base, in amdiommu_unmap_buf_locked() argument
341 KASSERT((domain->iodom.flags & IOMMU_DOMAIN_IDMAP) == 0, in amdiommu_unmap_buf_locked()
343 KASSERT((base & IOMMU_PAGE_MASK) == 0, in amdiommu_unmap_buf_locked()
344 ("non-aligned base %p %jx %jx", domain, (uintmax_t)base, in amdiommu_unmap_buf_locked()
347 ("non-aligned size %p %jx %jx", domain, (uintmax_t)base, in amdiommu_unmap_buf_locked()
349 KASSERT(base < DOM2IODOM(domain)->end, in amdiommu_unmap_buf_locked()
350 ("base too high %p %jx %jx end %jx", domain, (uintmax_t)base, in amdiommu_unmap_buf_locked()
351 (uintmax_t)size, (uintmax_t)DOM2IODOM(domain)->end)); in amdiommu_unmap_buf_locked()
352 KASSERT(base + size < DOM2IODOM(domain)->end, in amdiommu_unmap_buf_locked()
353 ("end too high %p %jx %jx end %jx", domain, (uintmax_t)base, in amdiommu_unmap_buf_locked()
354 (uintmax_t)size, (uintmax_t)DOM2IODOM(domain)->end)); in amdiommu_unmap_buf_locked()
355 KASSERT(base + size > base, in amdiommu_unmap_buf_locked()
356 ("size overflow %p %jx %jx", domain, (uintmax_t)base, in amdiommu_unmap_buf_locked()
363 for (sf = NULL; size > 0; base += pg_sz, size -= pg_sz) { in amdiommu_unmap_buf_locked()
364 pte = amdiommu_pgtbl_map_pte(domain, base, in amdiommu_unmap_buf_locked()
365 domain->pglvl - 1, flags, &idx, &sf); in amdiommu_unmap_buf_locked()
368 domain, (uintmax_t)base, domain->pglvl - 1, flags)); in amdiommu_unmap_buf_locked()
369 amdiommu_unmap_clear_pte(domain, base, domain->pglvl - 1, in amdiommu_unmap_buf_locked()
373 (uintmax_t)base, (uintmax_t)size, (uintmax_t)pg_sz)); in amdiommu_unmap_buf_locked()
390 error = amdiommu_unmap_buf_locked(domain, entry->start, in amdiommu_unmap_buf()
391 entry->end - entry->start, flags, entry); in amdiommu_unmap_buf()