Home | History | Annotate | Line # | Download | only in m68k
      1 /* $NetBSD: bus_dma.c,v 1.44 2026/05/06 04:45:03 thorpej Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9  * NASA Ames Research Center.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #include "opt_m68k_arch.h"
     34 
     35 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
     36 
     37 __KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.44 2026/05/06 04:45:03 thorpej Exp $");
     38 
     39 #define _M68K_BUS_DMA_PRIVATE
     40 
     41 #include <sys/param.h>
     42 #include <sys/systm.h>
     43 #include <sys/kernel.h>
     44 #include <sys/device.h>
     45 #include <sys/kmem.h>
     46 #include <sys/proc.h>
     47 #include <sys/mbuf.h>
     48 
     49 #include <uvm/uvm.h>
     50 
     51 #include <machine/cpu.h>
     52 #include <machine/bus.h>
     53 #include <m68k/cacheops.h>
     54 
     55 static size_t
     56 _bus_dmamap_mapsize(int const nsegments)
     57 {
     58 	KASSERT(nsegments > 0);
     59 	return sizeof(struct m68k_bus_dmamap) +
     60 	   (sizeof(bus_dma_segment_t) * (nsegments - 1));
     61 }
     62 
     63 /*
     64  * Common function for DMA map creation.  May be called by bus-specific
     65  * DMA map creation functions.
     66  */
     67 int
     68 _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments,
     69     bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
     70 {
     71 	struct m68k_bus_dmamap *map;
     72 	void *mapstore;
     73 
     74 	/*
     75 	 * Allocate and initialize the DMA map.  The end of the map
     76 	 * is a variable-sized array of segments, so we allocate enough
     77 	 * room for them in one shot.
     78 	 *
     79 	 * Note we don't preserve the WAITOK or NOWAIT flags.  Preservation
     80 	 * of ALLOCNOW notifies others that we've reserved these resources,
     81 	 * and they are not to be freed.
     82 	 *
     83 	 * The bus_dmamap_t includes one bus_dma_segment_t, hence
     84 	 * the (nsegments - 1).
     85 	 */
     86 	if ((mapstore = kmem_zalloc(_bus_dmamap_mapsize(nsegments),
     87 	    (flags & BUS_DMA_NOWAIT) ? KM_NOSLEEP : KM_SLEEP)) == NULL)
     88 		return ENOMEM;
     89 
     90 	map = (struct m68k_bus_dmamap *)mapstore;
     91 	map->_dm_size = size;
     92 	map->_dm_segcnt = nsegments;
     93 	map->_dm_maxmaxsegsz = maxsegsz;
     94 	if (t->_boundary != 0 && (boundary == 0 || t->_boundary < boundary))
     95 		map->_dm_boundary = t->_boundary;
     96 	else
     97 		map->_dm_boundary = boundary;
     98 	map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
     99 	map->dm_maxsegsz = maxsegsz;
    100 	map->dm_mapsize = 0;		/* no valid mappings */
    101 	map->dm_nsegs = 0;
    102 
    103 	*dmamp = map;
    104 	return 0;
    105 }
    106 
    107 /*
    108  * Common function for DMA map destruction.  May be called by bus-specific
    109  * DMA map destruction functions.
    110  */
    111 void
    112 _bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map)
    113 {
    114 
    115 	kmem_free(map, _bus_dmamap_mapsize(map->_dm_segcnt));
    116 }
    117 
    118 /*
    119  * Utility function to load a linear buffer.  lastaddrp holds state
    120  * between invocations (for multiple-buffer loads).  segp contains
    121  * the starting segment on entrance, and the ending segment on exit.
    122  * first indicates if this is the first invocation of this function.
    123  */
    124 static int
    125 _bus_dmamap_load_buffer_direct_common(bus_dma_tag_t t, bus_dmamap_t map,
    126     void *buf, bus_size_t buflen, struct vmspace *vm, int flags,
    127     paddr_t *lastaddrp, int *segp, int first)
    128 {
    129 	bus_size_t sgsize;
    130 	bus_addr_t curaddr, lastaddr, baddr, bmask;
    131 	vaddr_t vaddr = (vaddr_t)buf;
    132 	int seg, cacheable, coherent = BUS_DMA_COHERENT;
    133 	pmap_t pmap;
    134 	bool rv __diagused;
    135 
    136 	lastaddr = *lastaddrp;
    137 	bmask = ~(map->_dm_boundary - 1);
    138 
    139 	if (!VMSPACE_IS_KERNEL_P(vm))
    140 		pmap = vm_map_pmap(&vm->vm_map);
    141 	else
    142 		pmap = pmap_kernel();
    143 
    144 	for (seg = *segp; buflen > 0 ; ) {
    145 		/*
    146 		 * Get the physical address for this segment.
    147 		 */
    148 #if defined(__HAVE_NEW_PMAP_68K)
    149 		rv = pmap_extract_info(pmap, vaddr, &curaddr, &cacheable);
    150 		KASSERT(rv);
    151 		cacheable = !(cacheable & PMAP_NOCACHE);
    152 #else
    153 		rv = pmap_extract(pmap, vaddr, (paddr_t *) &curaddr);
    154 		KASSERT(rv);
    155 		cacheable = _pmap_page_is_cacheable(pmap, vaddr);
    156 #endif /* __HAVE_NEW_PMAP_68K */
    157 
    158 		if (cacheable)
    159 			coherent = 0;
    160 
    161 		/*
    162 		 * Compute the segment size, and adjust counts.
    163 		 */
    164 		sgsize = PAGE_SIZE - ((u_long)vaddr & PAGE_MASK);
    165 		if (buflen < sgsize)
    166 			sgsize = buflen;
    167 
    168 		/*
    169 		 * Make sure we don't cross any boundaries.
    170 		 */
    171 		if (map->_dm_boundary > 0) {
    172 			baddr = (curaddr + map->_dm_boundary) & bmask;
    173 			if (sgsize > (baddr - curaddr))
    174 				sgsize = (baddr - curaddr);
    175 		}
    176 
    177 		/*
    178 		 * Insert chunk into a segment, coalescing with
    179 		 * the previous segment if possible.
    180 		 */
    181 		if (first) {
    182 			map->dm_segs[seg].ds_addr =
    183 			    map->dm_segs[seg]._ds_cpuaddr = curaddr;
    184 			map->dm_segs[seg].ds_len = sgsize;
    185 			map->dm_segs[seg]._ds_flags =
    186 			    cacheable ? 0 : BUS_DMA_COHERENT;
    187 			first = 0;
    188 		} else {
    189 			if (curaddr == lastaddr &&
    190 			    (map->dm_segs[seg].ds_len + sgsize) <=
    191 			     map->dm_maxsegsz &&
    192 			    (map->_dm_boundary == 0 ||
    193 			     (map->dm_segs[seg].ds_addr & bmask) ==
    194 			     (curaddr & bmask)))
    195 				map->dm_segs[seg].ds_len += sgsize;
    196 			else {
    197 				if (++seg >= map->_dm_segcnt)
    198 					break;
    199 				map->dm_segs[seg].ds_addr =
    200 				    map->dm_segs[seg]._ds_cpuaddr = curaddr;
    201 				map->dm_segs[seg].ds_len = sgsize;
    202 				map->dm_segs[seg]._ds_flags =
    203 				    cacheable ? 0 : BUS_DMA_COHERENT;
    204 			}
    205 		}
    206 
    207 		lastaddr = curaddr + sgsize;
    208 		vaddr += sgsize;
    209 		buflen -= sgsize;
    210 	}
    211 
    212 	*segp = seg;
    213 	*lastaddrp = lastaddr;
    214 
    215 	/* BUS_DMA_COHERENT is set only if all segments are uncached */
    216 	map->_dm_flags &= ~BUS_DMA_COHERENT;
    217 	map->_dm_flags |= coherent;
    218 
    219 	/*
    220 	 * Did we fit?
    221 	 */
    222 	if (buflen != 0) {
    223 		/*
    224 		 * If there is a chained window, we will automatically
    225 		 * fall back to it.
    226 		 */
    227 		return EFBIG;		/* XXX better return value here? */
    228 	}
    229 
    230 	return 0;
    231 }
    232 
    233 /*
    234  * Common function for loading a direct-mapped DMA map with a linear
    235  * buffer.  Called by bus-specific DMA map load functions with the
    236  * OR value appropriate for indicating "direct-mapped" for that
    237  * chipset.
    238  */
    239 int
    240 _bus_dmamap_load_direct(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
    241     bus_size_t buflen, struct proc *p, int flags)
    242 {
    243 	paddr_t lastaddr;
    244 	int seg, error;
    245 	struct vmspace *vm;
    246 
    247 	/*
    248 	 * Make sure that on error condition we return "no valid mappings".
    249 	 */
    250 	map->dm_mapsize = 0;
    251 	map->dm_nsegs = 0;
    252 	KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
    253 
    254 	if (buflen > map->_dm_size)
    255 		return (EINVAL);
    256 
    257 	if (p != NULL) {
    258 		vm = p->p_vmspace;
    259 	} else {
    260 		vm = vmspace_kernel();
    261 	}
    262 
    263 	seg = 0;
    264 	error = _bus_dmamap_load_buffer_direct_common(t, map, buf, buflen,
    265 	    vm, flags, &lastaddr, &seg, 1);
    266 	if (error == 0) {
    267 		map->dm_mapsize = buflen;
    268 		map->dm_nsegs = seg + 1;
    269 	}
    270 	return error;
    271 }
    272 
    273 /*
    274  * Like _bus_dmamap_load_direct_common(), but for mbufs.
    275  */
    276 int
    277 _bus_dmamap_load_mbuf_direct(bus_dma_tag_t t, bus_dmamap_t map,
    278     struct mbuf *m0, int flags)
    279 {
    280 	paddr_t lastaddr;
    281 	int seg, error, first;
    282 	struct mbuf *m;
    283 
    284 	/*
    285 	 * Make sure that on error condition we return "no valid mappings."
    286 	 */
    287 	map->dm_mapsize = 0;
    288 	map->dm_nsegs = 0;
    289 	KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
    290 
    291 	KASSERT((m0->m_flags & M_PKTHDR) != 0);
    292 
    293 	if (m0->m_pkthdr.len > map->_dm_size)
    294 		return EINVAL;
    295 
    296 	first = 1;
    297 	seg = 0;
    298 	error = 0;
    299 	for (m = m0; m != NULL && error == 0; m = m->m_next) {
    300 		if (m->m_len == 0)
    301 			continue;
    302 		error = _bus_dmamap_load_buffer_direct_common(t, map,
    303 		    m->m_data, m->m_len, vmspace_kernel(), flags, &lastaddr,
    304 		    &seg, first);
    305 		first = 0;
    306 	}
    307 	if (error == 0) {
    308 		map->dm_mapsize = m0->m_pkthdr.len;
    309 		map->dm_nsegs = seg + 1;
    310 	}
    311 	return error;
    312 }
    313 
    314 /*
    315  * Like _bus_dmamap_load_direct_common(), but for uios.
    316  */
    317 int
    318 _bus_dmamap_load_uio_direct(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio,
    319     int flags)
    320 {
    321 	paddr_t lastaddr;
    322 	int seg, i, error, first;
    323 	bus_size_t minlen, resid;
    324 	struct iovec *iov;
    325 	void *addr;
    326 
    327 	/*
    328 	 * Make sure that on error condition we return "no valid mappings."
    329 	 */
    330 	map->dm_mapsize = 0;
    331 	map->dm_nsegs = 0;
    332 	KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
    333 
    334 	resid = uio->uio_resid;
    335 	iov = uio->uio_iov;
    336 
    337 	first = 1;
    338 	seg = 0;
    339 	error = 0;
    340 	for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) {
    341 		/*
    342 		 * Now at the first iovec to load.  Load each iovec
    343 		 * until we have exhausted the residual count.
    344 		 */
    345 		minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
    346 		addr = (void *)iov[i].iov_base;
    347 
    348 		error = _bus_dmamap_load_buffer_direct_common(t, map,
    349 		    addr, minlen, uio->uio_vmspace, flags, &lastaddr, &seg,
    350 		    first);
    351 		first = 0;
    352 
    353 		resid -= minlen;
    354 	}
    355 	if (error == 0) {
    356 		map->dm_mapsize = uio->uio_resid;
    357 		map->dm_nsegs = seg + 1;
    358 	}
    359 	return error;
    360 }
    361 
    362 /*
    363  * Like _bus_dmamap_load_direct_common(), but for raw memory.
    364  */
    365 int
    366 _bus_dmamap_load_raw_direct(bus_dma_tag_t t, bus_dmamap_t map,
    367     bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags)
    368 {
    369 	int i;
    370 
    371 	/*
    372 	 * @@@ This routine doesn't enforce map boundary requirement
    373 	 * @@@ perhaps it should return an error instead of panicking
    374 	 */
    375 
    376 	KASSERT(size <= map->_dm_size);
    377 	KASSERT(nsegs <= map->_dm_segcnt);
    378 
    379 	for (i = 0; i < nsegs; i++) {
    380 		KASSERT(map->dm_segs[i].ds_len <= map->dm_maxsegsz);
    381 		map->dm_segs[i] = segs[i];
    382 	}
    383 
    384 	map->dm_nsegs   = nsegs;
    385 	map->dm_mapsize = size;
    386 
    387 	return 0;
    388 }
    389 
    390 /*
    391  * Common function for unloading a DMA map.  May be called by
    392  * chipset-specific DMA map unload functions.
    393  */
    394 void
    395 _bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map)
    396 {
    397 
    398 	/*
    399 	 * No resources to free; just mark the mappings as
    400 	 * invalid.
    401 	 */
    402 	map->dm_maxsegsz = map->_dm_maxmaxsegsz;
    403 	map->dm_mapsize = 0;
    404 	map->dm_nsegs = 0;
    405 	map->_dm_flags &= ~BUS_DMA_COHERENT;
    406 }
    407 
    408 #if defined(M68010) || defined(M68020)
    409 /*
    410  * DMA map synchronization for the 68010 and 68020.  These CPUs don't
    411  * have on-chip data caches at all, so this is a no-op unless there's
    412  * an external cache.
    413  */
    414 void
    415 _bus_dmamap_sync_1020(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
    416     bus_size_t len, int ops)
    417 {
    418 #ifdef M68K_EC
    419 	/* If the whole DMA map is uncached, do nothing.  */
    420 	if (map->_dm_flags & BUS_DMA_COHERENT)
    421 		return;
    422 
    423 	if (ectype != EC_NONE) {
    424 		/*
    425 		 * See explainer below in _bus_dmamap_sync_30().
    426 		 */
    427 		if (ops & BUS_DMASYNC_PREREAD) {
    428 			PCIA();
    429 		}
    430 	}
    431 #endif
    432 	return;
    433 }
    434 #endif /* M68010 || M68020 */
    435 
    436 #if defined(M68030)
    437 /*
    438  * 68030 DMA map synchronization.  May be called
    439  * by chipset-specific DMA map synchronization functions.
    440  */
    441 void
    442 _bus_dmamap_sync_30(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
    443     bus_size_t len, int ops)
    444 {
    445 	/* If the whole DMA map is uncached, do nothing.  */
    446 	if (map->_dm_flags & BUS_DMA_COHERENT)
    447 		return;
    448 
    449 	/*
    450 	 * 68030 caches are write-through, so this is trivial; we only
    451 	 * need to invalidate the cache (on-chip and external, if present)
    452 	 * before a DMA read.
    453 	 *
    454 	 * We do this in PREREAD to remain aligned with the 68040/68060
    455 	 * implementation, which also needs to do this work in PREREAD
    456 	 * (since write-backs may be involved).  We obviously don't have
    457 	 * to worry about write-backs here, but this should mean that
    458 	 * programming errors that cause cache-fills from the memory region
    459 	 * that's part of the DMA operation would tend to show up on both
    460 	 * CPU types.
    461 	 */
    462 	if (ops & BUS_DMASYNC_PREREAD) {
    463 		PCIA();
    464 	}
    465 }
    466 #endif /* M68030 */
    467 
    468 #if defined(M68040) || defined(M68060)
    469 /*
    470  * 68040/68060 DMA map synchronization.  May be called
    471  * by chipset-specific DMA map synchronization functions.
    472  */
    473 void
    474 _bus_dmamap_sync_4060(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
    475     bus_size_t len, int ops)
    476 {
    477 	bus_addr_t p, e, ps, pe;
    478 	bus_size_t seglen;
    479 	bus_dma_segment_t *seg;
    480 	int i;
    481 
    482 	/* If the whole DMA map is uncached, do nothing. */
    483 	if ((map->_dm_flags & BUS_DMA_COHERENT) != 0)
    484 		return;
    485 
    486 	/* Short-circuit for unsupported `ops' */
    487 	if ((ops & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)) == 0)
    488 		return;
    489 
    490 	for (i = 0; i < map->dm_nsegs && len != 0; i++) {
    491 		seg = &map->dm_segs[i];
    492 		if (seg->ds_len <= offset) {
    493 			/* Segment irrelevant - before requested offset */
    494 			offset -= seg->ds_len;
    495 			continue;
    496 		}
    497 
    498 		/*
    499 		 * Now at the first segment to sync; nail
    500 		 * each segment until we have exhausted the
    501 		 * length.
    502 		 */
    503 		seglen = seg->ds_len - offset;
    504 		if (seglen > len)
    505 			seglen = len;
    506 		len -= seglen;
    507 		offset = 0;
    508 
    509 		/* Ignore cache-inhibited segments */
    510 		if ((seg->_ds_flags & BUS_DMA_COHERENT) != 0)
    511 			continue;
    512 
    513 		ps = seg->_ds_cpuaddr + offset;
    514 		pe = ps + seglen;
    515 
    516 		/* N.B. '40 cache ops are the same as '60 */
    517 
    518 		if (ops & BUS_DMASYNC_PREWRITE) {
    519 			p = ps & ~CACHELINE_MASK;
    520 			e = (pe + CACHELINE_MASK) & ~CACHELINE_MASK;
    521 
    522 			/* flush cacheline */
    523 			while ((p < e) && (p & (CACHELINE_SIZE * 8 - 1)) != 0) {
    524 				DCFL_40(p);
    525 				p += CACHELINE_SIZE;
    526 			}
    527 
    528 			/* flush cachelines per 128bytes */
    529 			while ((p + CACHELINE_SIZE * 8 <= e) &&
    530 			    (p & PAGE_MASK) != 0) {
    531 				DCFL_40(p);
    532 				p += CACHELINE_SIZE;
    533 				DCFL_40(p);
    534 				p += CACHELINE_SIZE;
    535 				DCFL_40(p);
    536 				p += CACHELINE_SIZE;
    537 				DCFL_40(p);
    538 				p += CACHELINE_SIZE;
    539 				DCFL_40(p);
    540 				p += CACHELINE_SIZE;
    541 				DCFL_40(p);
    542 				p += CACHELINE_SIZE;
    543 				DCFL_40(p);
    544 				p += CACHELINE_SIZE;
    545 				DCFL_40(p);
    546 				p += CACHELINE_SIZE;
    547 			}
    548 
    549 			/* flush page */
    550 			while (p + PAGE_SIZE <= e) {
    551 				DCFP_40(p);
    552 				p += PAGE_SIZE;
    553 			}
    554 
    555 			/* flush cachelines per 128bytes */
    556 			while (p + CACHELINE_SIZE * 8 <= e) {
    557 				DCFL_40(p);
    558 				p += CACHELINE_SIZE;
    559 				DCFL_40(p);
    560 				p += CACHELINE_SIZE;
    561 				DCFL_40(p);
    562 				p += CACHELINE_SIZE;
    563 				DCFL_40(p);
    564 				p += CACHELINE_SIZE;
    565 				DCFL_40(p);
    566 				p += CACHELINE_SIZE;
    567 				DCFL_40(p);
    568 				p += CACHELINE_SIZE;
    569 				DCFL_40(p);
    570 				p += CACHELINE_SIZE;
    571 				DCFL_40(p);
    572 				p += CACHELINE_SIZE;
    573 			}
    574 
    575 			/* flush cacheline */
    576 			while (p < e) {
    577 				DCFL_40(p);
    578 				p += CACHELINE_SIZE;
    579 			}
    580 		}
    581 
    582 		/*
    583 		 * Normally, the `PREREAD' flag instructs us to purge the
    584 		 * cache for the specified offset and length. However, if
    585 		 * the offset/length is not aligned to a cacheline boundary,
    586 		 * we may end up purging some legitimate data from the
    587 		 * start/end of the cache. In such a case, *flush* the
    588 		 * cachelines at the start and end of the required region.
    589 		 */
    590 		else if (ops & BUS_DMASYNC_PREREAD) {
    591 			/* flush cacheline on start boundary */
    592 			if (ps & CACHELINE_MASK) {
    593 				DCFL_40(ps & ~CACHELINE_MASK);
    594 			}
    595 
    596 			p = (ps + CACHELINE_MASK) & ~CACHELINE_MASK;
    597 			e = pe & ~CACHELINE_MASK;
    598 
    599 			/* purge cacheline */
    600 			while ((p < e) && (p & (CACHELINE_SIZE * 8 - 1)) != 0) {
    601 				DCPL_40(p);
    602 				p += CACHELINE_SIZE;
    603 			}
    604 
    605 			/* purge cachelines per 128bytes */
    606 			while ((p + CACHELINE_SIZE * 8 <= e) &&
    607 			    (p & PAGE_MASK) != 0) {
    608 				DCPL_40(p);
    609 				p += CACHELINE_SIZE;
    610 				DCPL_40(p);
    611 				p += CACHELINE_SIZE;
    612 				DCPL_40(p);
    613 				p += CACHELINE_SIZE;
    614 				DCPL_40(p);
    615 				p += CACHELINE_SIZE;
    616 				DCPL_40(p);
    617 				p += CACHELINE_SIZE;
    618 				DCPL_40(p);
    619 				p += CACHELINE_SIZE;
    620 				DCPL_40(p);
    621 				p += CACHELINE_SIZE;
    622 				DCPL_40(p);
    623 				p += CACHELINE_SIZE;
    624 			}
    625 
    626 			/* purge page */
    627 			while (p + PAGE_SIZE <= e) {
    628 				DCPP_40(p);
    629 				ICPP_40(p);
    630 				p += PAGE_SIZE;
    631 			}
    632 
    633 			/* purge cachelines per 128bytes */
    634 			while (p + CACHELINE_SIZE * 8 <= e) {
    635 				DCPL_40(p);
    636 				p += CACHELINE_SIZE;
    637 				DCPL_40(p);
    638 				p += CACHELINE_SIZE;
    639 				DCPL_40(p);
    640 				p += CACHELINE_SIZE;
    641 				DCPL_40(p);
    642 				p += CACHELINE_SIZE;
    643 				DCPL_40(p);
    644 				p += CACHELINE_SIZE;
    645 				DCPL_40(p);
    646 				p += CACHELINE_SIZE;
    647 				DCPL_40(p);
    648 				p += CACHELINE_SIZE;
    649 				DCPL_40(p);
    650 				p += CACHELINE_SIZE;
    651 			}
    652 
    653 			/* purge cacheline */
    654 			while (p < e) {
    655 				DCPL_40(p);
    656 				p += CACHELINE_SIZE;
    657 			}
    658 
    659 			/* flush cacheline on end boundary */
    660 			if (p < pe) {
    661 				DCFL_40(p);
    662 			}
    663 		}
    664 	}
    665 }
    666 #endif /* M68040 || M68060 */
    667 
    668 /*
    669  * If we're configured for only a single CPU cache class, then resolve
    670  * the DMA map sync routine at compile time.
    671  */
    672 #if    (defined(M68010) || defined(M68020)) && \
    673       !(defined(M68030) || defined(M68040) || defined(M68060))
    674 __strong_alias(_bus_dmamap_sync,_bus_dmamap_sync_1020)
    675 #elif   defined(M68030) && \
    676       !(defined(M68010) || defined(M68020) || defined(M68040) || \
    677         defined(M68060))
    678 __strong_alias(_bus_dmamap_sync,_bus_dmamap_sync_30)
    679 #elif  (defined(M68040) || defined(M68060)) && \
    680       !(defined(M68010) || defined(M68020) || defined(M68030))
    681 __strong_alias(_bus_dmamap_sync,_bus_dmamap_sync_4060)
    682 #else /* run-time */
    683 void
    684 _bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
    685     bus_size_t len, int ops)
    686 {
    687 	switch (cputype) {
    688 #if defined(M68010) || defined(M68020)
    689 	case CPU_68010:
    690 	case CPU_68020:
    691 		_bus_dmamap_sync_1020(t, map, offset, len, ops);
    692 		break;
    693 #endif
    694 #if defined(M68030)
    695 	case CPU_68030:
    696 		_bus_dmamap_sync_30(t, map, offset, len, ops);
    697 		break;
    698 #endif
    699 #if defined(M68040) || defined(M68060)
    700 	case CPU_68040:
    701 	case CPU_68060:
    702 		_bus_dmamap_sync_4060(t, map, offset, len, ops);
    703 		break;
    704 #endif
    705 	default:
    706 		panic("%s", __func__);
    707 	}
    708 }
    709 #endif /* CPU cache class */
    710 
    711 /*
    712  * Common function for DMA-safe memory allocation.  May be called
    713  * by bus-specific DMA memory allocation functions.
    714  */
    715 int
    716 _bus_dmamem_alloc_common(bus_dma_tag_t t, bus_addr_t low, bus_addr_t high,
    717     bus_size_t size, bus_size_t alignment, bus_size_t boundary,
    718     bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags)
    719 {
    720 	paddr_t curaddr, lastaddr;
    721 	struct vm_page *m;
    722 	struct pglist mlist;
    723 	int curseg, error;
    724 
    725 	/* Constrain the upper-bound, if needed. */
    726 	if (flags & BUS_DMA_24BIT) {
    727 		if (low >= 0x01000000u) {
    728 			/* Can't satisfy the request. */
    729 			return EINVAL;
    730 		}
    731 		if (high & 0xff000000u) {
    732 			high = 0x01000000u;
    733 		}
    734 	}
    735 
    736 	/* Always round the size. */
    737 	size = round_page(size);
    738 	high -= PAGE_SIZE;
    739 
    740 	/*
    741 	 * Allocate pages from the VM system.
    742 	 *
    743 	 * XXX mvme68k-specific comment
    744 	 * XXXSCW: This will be sub-optimal if the base-address of offboard
    745 	 * RAM is significantly higher than the end-address of onboard RAM.
    746 	 * (Due to how uvm_pglistalloc() is implemented.)
    747 	 *
    748 	 * uvm_pglistalloc() also currently ignores the 'nsegs' parameter,
    749 	 * and always returns only one (contiguous) segment.
    750 	 */
    751 	error = uvm_pglistalloc(size, low, high, alignment, boundary,
    752 	    &mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0);
    753 	if (error)
    754 		return error;
    755 
    756 	/*
    757 	 * Compute the location, size, and number of segments actually
    758 	 * returned by the VM code.
    759 	 */
    760 	m = mlist.tqh_first;
    761 	curseg = 0;
    762 	lastaddr = VM_PAGE_TO_PHYS(m);
    763 	segs[curseg].ds_addr = segs[curseg]._ds_cpuaddr = lastaddr;
    764 	segs[curseg].ds_len = PAGE_SIZE;
    765 	segs[curseg]._ds_flags = 0;
    766 	m = m->pageq.queue.tqe_next;
    767 
    768 	for (; m != NULL; m = m->pageq.queue.tqe_next) {
    769 		curaddr = VM_PAGE_TO_PHYS(m);
    770 		KASSERT(curaddr >= low);
    771 		KASSERT(curaddr < high);
    772 
    773 		if (curaddr == (lastaddr + PAGE_SIZE))
    774 			segs[curseg].ds_len += PAGE_SIZE;
    775 		else {
    776 			if (++curseg >= nsegs) {
    777 #ifdef DIAGNOSTIC
    778 				printf("%s: too many segments\n", __func__);
    779 #ifdef DEBUG
    780 				panic("%s", __func__);
    781 #endif
    782 #endif
    783 				uvm_pglistfree(&mlist);
    784 				return -1;
    785 			}
    786 			segs[curseg].ds_addr =
    787 			    segs[curseg]._ds_cpuaddr = curaddr;
    788 			segs[curseg].ds_len = PAGE_SIZE;
    789 			segs[curseg]._ds_flags = 0;
    790 		}
    791 		lastaddr = curaddr;
    792 	}
    793 
    794 	*rsegs = curseg + 1;
    795 
    796 	return 0;
    797 }
    798 
    799 /*
    800  * Common function for DMA-safe memory allocation.  May be called
    801  * by bus-specific DMA memory allocation functions.
    802  */
    803 int
    804 _bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
    805     bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
    806     int flags)
    807 {
    808 	extern paddr_t avail_start, avail_end;
    809 
    810 	return _bus_dmamem_alloc_common(t, avail_start, avail_end,
    811 	    size, alignment, boundary, segs, nsegs, rsegs, flags);
    812 }
    813 
    814 /*
    815  * Common function for freeing DMA-safe memory.  May be called by
    816  * bus-specific DMA memory free functions.
    817  */
    818 void
    819 _bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs)
    820 {
    821 	struct vm_page *m;
    822 	bus_addr_t addr;
    823 	struct pglist mlist;
    824 	int curseg;
    825 
    826 	/*
    827 	 * Build a list of pages to free back to the VM system.
    828 	 */
    829 	TAILQ_INIT(&mlist);
    830 	for (curseg = 0; curseg < nsegs; curseg++) {
    831 		for (addr = segs[curseg]._ds_cpuaddr;
    832 		    addr < (segs[curseg]._ds_cpuaddr + segs[curseg].ds_len);
    833 		    addr += PAGE_SIZE) {
    834 			m = PHYS_TO_VM_PAGE(addr);
    835 			TAILQ_INSERT_TAIL(&mlist, m, pageq.queue);
    836 		}
    837 	}
    838 
    839 	uvm_pglistfree(&mlist);
    840 }
    841 
    842 /*
    843  * Common function for mapping DMA-safe memory.  May be called by
    844  * bus-specific DMA memory map functions.
    845  */
    846 int
    847 _bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
    848     size_t size, void **kvap, int flags)
    849 {
    850 	vaddr_t va;
    851 	bus_addr_t addr;
    852 	int curseg;
    853 	const uvm_flag_t kmflags =
    854 	    (flags & BUS_DMA_NOWAIT) != 0 ? UVM_KMF_NOWAIT : 0;
    855 	const int pmap_flags =
    856 	    VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED |
    857 	    ((flags & BUS_DMA_COHERENT) ? PMAP_NOCACHE : 0);
    858 
    859 	size = round_page(size);
    860 
    861 	va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags);
    862 
    863 	if (va == 0)
    864 		return ENOMEM;
    865 
    866 	*kvap = (void *)va;
    867 
    868 	for (curseg = 0; curseg < nsegs; curseg++) {
    869 		for (addr = segs[curseg]._ds_cpuaddr;
    870 		    addr < (segs[curseg]._ds_cpuaddr + segs[curseg].ds_len);
    871 		    addr += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE) {
    872 			if (size == 0)
    873 				panic("%s: size botch", __func__);
    874 
    875 			pmap_enter(pmap_kernel(), va, addr,
    876 			    VM_PROT_READ | VM_PROT_WRITE, pmap_flags);
    877 
    878 #if !defined(__HAVE_NEW_PMAP_68K)
    879 			/* Cache-inhibit the page if necessary */
    880 			if ((flags & BUS_DMA_COHERENT) != 0)
    881 				_pmap_set_page_cacheinhibit(pmap_kernel(), va);
    882 #endif /* ! __HAVE_NEW_PMAP_68K */
    883 
    884 			segs[curseg]._ds_flags &= ~BUS_DMA_COHERENT;
    885 			segs[curseg]._ds_flags |= (flags & BUS_DMA_COHERENT);
    886 		}
    887 	}
    888 	pmap_update(pmap_kernel());
    889 
    890 	if ((flags & BUS_DMA_COHERENT) != 0)
    891 		TBIAS();
    892 
    893 	return 0;
    894 }
    895 
    896 /*
    897  * Common function for unmapping DMA-safe memory.  May be called by
    898  * bus-specific DMA memory unmapping functions.
    899  */
    900 void
    901 _bus_dmamem_unmap(bus_dma_tag_t t, void *kva, size_t size)
    902 {
    903 	vaddr_t va;
    904 
    905 	KASSERT(((vaddr_t)kva & PAGE_MASK) == 0);
    906 
    907 	size = round_page(size);
    908 
    909 #if !defined(__HAVE_NEW_PMAP_68K)
    910 	/*
    911 	 * Re-enable cacheing on the range
    912 	 * XXXSCW: There should be some way to indicate that the pages
    913 	 * were mapped DMA_MAP_COHERENT in the first place...
    914 	 */
    915 	size_t s;
    916 
    917 	for (s = 0, va = (vaddr_t)kva; s < size;
    918 	    s += PAGE_SIZE, va += PAGE_SIZE)
    919 		_pmap_set_page_cacheable(pmap_kernel(), va);
    920 #endif /* __HAVE_NEW_PMAP_68K */
    921 
    922 	va = (vaddr_t)kva;
    923 	pmap_remove(pmap_kernel(), va, (vaddr_t)kva + size);
    924 	pmap_update(pmap_kernel());
    925 	uvm_km_free(kernel_map, (vaddr_t)kva, size, UVM_KMF_VAONLY);
    926 }
    927 
    928 /*
    929  * Common function for mmap(2)'ing DMA-safe memory.  May be called by
    930  * bus-specific DMA mmap(2)'ing functions.
    931  */
    932 paddr_t
    933 _bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, off_t off,
    934     int prot, int flags)
    935 {
    936 	int i;
    937 
    938 	for (i = 0; i < nsegs; i++) {
    939 		KASSERT((off & PAGE_MASK) == 0);
    940 		KASSERT((segs[i].ds_addr & PAGE_MASK) == 0);
    941 		KASSERT((segs[i].ds_len & PAGE_MASK) == 0);
    942 
    943 		if (off >= segs[i].ds_len) {
    944 			off -= segs[i].ds_len;
    945 			continue;
    946 		}
    947 
    948 		/*
    949 		 * XXXSCW: What about BUS_DMA_COHERENT ??
    950 		 */
    951 
    952 		return m68k_btop((char *)segs[i]._ds_cpuaddr + off);
    953 	}
    954 
    955 	/* Page not found. */
    956 	return -1;
    957 }
    958