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
This commit is contained in:
Adrian Chadd
2026-02-17 22:50:12 -08:00
parent df3bd7201e
commit 00ec88d2aa
3 changed files with 74 additions and 38 deletions
+6
View File
@@ -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
+6 -35
View File
@@ -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)
+62 -3
View File
@@ -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.