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:
@@ -80,4 +80,10 @@ struct bus_dma_impl {
|
|||||||
|
|
||||||
extern struct bus_dma_impl bus_dma_bounce_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
|
#endif
|
||||||
|
|||||||
@@ -159,9 +159,6 @@ bounce_bus_dma_zone_setup(bus_dma_tag_t newtag)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a device specific dma_tag.
|
* 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
|
static int
|
||||||
bounce_bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
|
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 */
|
/* Return a NULL tag on failure */
|
||||||
*dmat = NULL;
|
*dmat = NULL;
|
||||||
|
|
||||||
newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF,
|
error = common_bus_dma_tag_create(parent != NULL ? &parent->common :
|
||||||
M_ZERO | M_NOWAIT);
|
NULL, alignment, boundary, lowaddr, highaddr, maxsize, nsegments,
|
||||||
if (newtag == NULL) {
|
maxsegsz, flags, lockfunc, lockfuncarg,
|
||||||
CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
|
sizeof (struct bus_dma_tag), (void **)&newtag);
|
||||||
__func__, newtag, 0, error);
|
if (error != 0)
|
||||||
return (ENOMEM);
|
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->map_count = 0;
|
||||||
newtag->common.impl = &bus_dma_bounce_impl;
|
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 */
|
/* Take into account any restrictions imposed by our parent tag */
|
||||||
if (parent != NULL) {
|
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 = parent->iommu;
|
||||||
newtag->iommu_cookie = parent->iommu_cookie;
|
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)
|
if (newtag->common.lowaddr < ptoa((vm_paddr_t)Maxmem) && newtag->iommu == NULL)
|
||||||
|
|||||||
@@ -53,10 +53,69 @@
|
|||||||
|
|
||||||
#include <machine/atomic.h>
|
#include <machine/atomic.h>
|
||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
#include <machine/cpufunc.h>
|
#include <machine/bus_dma_impl.h>
|
||||||
#include <machine/md_var.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.
|
* Allocate a device specific dma_tag.
|
||||||
|
|||||||
Reference in New Issue
Block a user