aboutsummaryrefslogtreecommitdiff
path: root/sys/powerpc
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2026-02-18 06:50:12 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2026-05-01 21:14:44 +0000
commit00ec88d2aa8d8267b1e80991d5e632bb9f012b07 (patch)
treec9dba5dcecaf8eb4ae503dade971f6cd0018eed8 /sys/powerpc
parentdf3bd7201efc88b0518c9fe7997f3dbf656eccd5 (diff)
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/include/bus_dma_impl.h6
-rw-r--r--sys/powerpc/powerpc/busdma_bounce.c41
-rw-r--r--sys/powerpc/powerpc/busdma_machdep.c65
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.