Skip site navigation (1)Skip section navigation (2)
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>