Date: Fri, 01 May 2026 21:15:20 +0000 From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 00ec88d2aa8d - main - powerpc: refactor common busdma tag setup Message-ID: <69f517e8.18a02.5f29002b@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=00ec88d2aa8d8267b1e80991d5e632bb9f012b07 commit 00ec88d2aa8d8267b1e80991d5e632bb9f012b07 Author: Adrian Chadd <adrian@FreeBSD.org> AuthorDate: 2026-02-18 06:50:12 +0000 Commit: Adrian Chadd <adrian@FreeBSD.org> CommitDate: 2026-05-01 21:14:44 +0000 powerpc: refactor common busdma tag setup Refactor the common busdma tag setup code into busdma_machdep.c Locally tested: * qemu VM, pseries-9 / power9 * qemu VM, pseries-8 / power8 Differential Revision: https://reviews.freebsd.org/D55340 --- sys/powerpc/include/bus_dma_impl.h | 6 ++++ sys/powerpc/powerpc/busdma_bounce.c | 41 ++++------------------- sys/powerpc/powerpc/busdma_machdep.c | 65 ++++++++++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 38 deletions(-) diff --git a/sys/powerpc/include/bus_dma_impl.h b/sys/powerpc/include/bus_dma_impl.h index 80d775f2cf9e..cb495236646d 100644 --- a/sys/powerpc/include/bus_dma_impl.h +++ b/sys/powerpc/include/bus_dma_impl.h @@ -80,4 +80,10 @@ struct bus_dma_impl { extern struct bus_dma_impl bus_dma_bounce_impl; +extern int common_bus_dma_tag_create(struct bus_dma_tag_common *parent, + bus_size_t alignment, bus_addr_t boundary, bus_addr_t lowaddr, + bus_addr_t highaddr, bus_size_t maxsize, int nsegments, + bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, + void *lockfuncarg, size_t sz, void **dmat); + #endif diff --git a/sys/powerpc/powerpc/busdma_bounce.c b/sys/powerpc/powerpc/busdma_bounce.c index 790903712da7..36c4d38cc7f6 100644 --- a/sys/powerpc/powerpc/busdma_bounce.c +++ b/sys/powerpc/powerpc/busdma_bounce.c @@ -159,9 +159,6 @@ bounce_bus_dma_zone_setup(bus_dma_tag_t newtag) /* * Allocate a device specific dma_tag. - * - * TODO: this does ALL of the work, rather than it being split into - * common and bounce specific. That'll need fixing. */ static int bounce_bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, @@ -184,46 +181,20 @@ bounce_bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, /* Return a NULL tag on failure */ *dmat = NULL; - newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, - M_ZERO | M_NOWAIT); - if (newtag == NULL) { - CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d", - __func__, newtag, 0, error); - return (ENOMEM); - } + error = common_bus_dma_tag_create(parent != NULL ? &parent->common : + NULL, alignment, boundary, lowaddr, highaddr, maxsize, nsegments, + maxsegsz, flags, lockfunc, lockfuncarg, + sizeof (struct bus_dma_tag), (void **)&newtag); + if (error != 0) + return (error); - newtag->common.alignment = alignment; - newtag->common.boundary = boundary; - newtag->common.lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1); - newtag->common.highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1); - newtag->common.maxsize = maxsize; - newtag->common.nsegments = nsegments; - newtag->common.maxsegsz = maxsegsz; - newtag->common.flags = flags; newtag->map_count = 0; newtag->common.impl = &bus_dma_bounce_impl; - if (lockfunc != NULL) { - newtag->common.lockfunc = lockfunc; - newtag->common.lockfuncarg = lockfuncarg; - } else { - newtag->common.lockfunc = _busdma_dflt_lock; - newtag->common.lockfuncarg = NULL; - } /* Take into account any restrictions imposed by our parent tag */ if (parent != NULL) { - newtag->common.lowaddr = MIN(parent->common.lowaddr, newtag->common.lowaddr); - newtag->common.highaddr = MAX(parent->common.highaddr, newtag->common.highaddr); - if (newtag->common.boundary == 0) - newtag->common.boundary = parent->common.boundary; - else if (parent->common.boundary != 0) - newtag->common.boundary = MIN(parent->common.boundary, - newtag->common.boundary); - newtag->iommu = parent->iommu; newtag->iommu_cookie = parent->iommu_cookie; - newtag->common.domain = vm_phys_domain_match(newtag->common.domain, 0ul, - newtag->common.lowaddr); } if (newtag->common.lowaddr < ptoa((vm_paddr_t)Maxmem) && newtag->iommu == NULL) diff --git a/sys/powerpc/powerpc/busdma_machdep.c b/sys/powerpc/powerpc/busdma_machdep.c index aba11e64145c..575b3fcbe2bf 100644 --- a/sys/powerpc/powerpc/busdma_machdep.c +++ b/sys/powerpc/powerpc/busdma_machdep.c @@ -53,10 +53,69 @@ #include <machine/atomic.h> #include <machine/bus.h> -#include <machine/cpufunc.h> -#include <machine/md_var.h> +#include <machine/bus_dma_impl.h> -#include "iommu_if.h" +int +common_bus_dma_tag_create(struct bus_dma_tag_common *parent, + bus_size_t alignment, bus_addr_t boundary, bus_addr_t lowaddr, + bus_addr_t highaddr, bus_size_t maxsize, int nsegments, + bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, + void *lockfuncarg, size_t sz, void **dmat) +{ + void *newtag; + struct bus_dma_tag_common *common; + + KASSERT(sz >= sizeof(struct bus_dma_tag_common), ("sz")); + /* Return a NULL tag on failure */ + *dmat = NULL; + /* Basic sanity checking */ + if (boundary != 0 && boundary < maxsegsz) + maxsegsz = boundary; + if (maxsegsz == 0) + return (EINVAL); + + newtag = malloc(sz, M_DEVBUF, M_ZERO | M_NOWAIT); + if (newtag == NULL) { + CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d", + __func__, newtag, 0, ENOMEM); + return (ENOMEM); + } + + common = newtag; + common->impl = &bus_dma_bounce_impl; + common->alignment = alignment; + common->boundary = boundary; + common->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1); + common->highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1); + common->maxsize = maxsize; + common->nsegments = nsegments; + common->maxsegsz = maxsegsz; + common->flags = flags; + if (lockfunc != NULL) { + common->lockfunc = lockfunc; + common->lockfuncarg = lockfuncarg; + } else { + common->lockfunc = _busdma_dflt_lock; + common->lockfuncarg = NULL; + } + + /* Take into account any restrictions imposed by our parent tag */ + if (parent != NULL) { + common->impl = parent->impl; + common->lowaddr = MIN(parent->lowaddr, common->lowaddr); + common->highaddr = MAX(parent->highaddr, common->highaddr); + if (common->boundary == 0) + common->boundary = parent->boundary; + else if (parent->boundary != 0) { + common->boundary = MIN(parent->boundary, + common->boundary); + } + common->domain = vm_phys_domain_match(common->domain, 0ul, + common->lowaddr); + } + *dmat = common; + return (0); +} /* * Allocate a device specific dma_tag.home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f517e8.18a02.5f29002b>
