xref: /freebsd/sys/dev/proto/proto_busdma.c (revision 90a1793cce2199c0744ba996c4d8638cceebb165)
14f027abdSMarcel Moolenaar /*-
24f027abdSMarcel Moolenaar  * Copyright (c) 2015 Marcel Moolenaar
34f027abdSMarcel Moolenaar  * All rights reserved.
44f027abdSMarcel Moolenaar  *
54f027abdSMarcel Moolenaar  * Redistribution and use in source and binary forms, with or without
64f027abdSMarcel Moolenaar  * modification, are permitted provided that the following conditions
74f027abdSMarcel Moolenaar  * are met:
84f027abdSMarcel Moolenaar  * 1. Redistributions of source code must retain the above copyright
94f027abdSMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer.
104f027abdSMarcel Moolenaar  * 2. Redistributions in binary form must reproduce the above copyright
114f027abdSMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer in the
124f027abdSMarcel Moolenaar  *    documentation and/or other materials provided with the distribution.
134f027abdSMarcel Moolenaar  *
144f027abdSMarcel Moolenaar  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
154f027abdSMarcel Moolenaar  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
164f027abdSMarcel Moolenaar  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
174f027abdSMarcel Moolenaar  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
184f027abdSMarcel Moolenaar  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
194f027abdSMarcel Moolenaar  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
204f027abdSMarcel Moolenaar  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
214f027abdSMarcel Moolenaar  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
224f027abdSMarcel Moolenaar  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
234f027abdSMarcel Moolenaar  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
244f027abdSMarcel Moolenaar  */
254f027abdSMarcel Moolenaar 
264f027abdSMarcel Moolenaar #include <sys/cdefs.h>
274f027abdSMarcel Moolenaar __FBSDID("$FreeBSD$");
284f027abdSMarcel Moolenaar 
294f027abdSMarcel Moolenaar #include <sys/param.h>
304f027abdSMarcel Moolenaar #include <sys/systm.h>
314f027abdSMarcel Moolenaar #include <machine/bus.h>
324f027abdSMarcel Moolenaar #include <machine/bus_dma.h>
334f027abdSMarcel Moolenaar #include <machine/resource.h>
344f027abdSMarcel Moolenaar #include <sys/bus.h>
354f027abdSMarcel Moolenaar #include <sys/conf.h>
364f027abdSMarcel Moolenaar #include <sys/kernel.h>
374f027abdSMarcel Moolenaar #include <sys/malloc.h>
384f027abdSMarcel Moolenaar #include <sys/module.h>
394f027abdSMarcel Moolenaar #include <sys/queue.h>
404f027abdSMarcel Moolenaar #include <sys/rman.h>
414f027abdSMarcel Moolenaar #include <sys/sbuf.h>
425dcca8e8SMarcel Moolenaar #include <vm/vm.h>
435dcca8e8SMarcel Moolenaar #include <vm/pmap.h>
444f027abdSMarcel Moolenaar 
454f027abdSMarcel Moolenaar #include <dev/proto/proto.h>
464f027abdSMarcel Moolenaar #include <dev/proto/proto_dev.h>
474f027abdSMarcel Moolenaar #include <dev/proto/proto_busdma.h>
484f027abdSMarcel Moolenaar 
494f027abdSMarcel Moolenaar MALLOC_DEFINE(M_PROTO_BUSDMA, "proto_busdma", "DMA management data");
504f027abdSMarcel Moolenaar 
514f027abdSMarcel Moolenaar static int
525dcca8e8SMarcel Moolenaar proto_busdma_tag_create(struct proto_busdma *busdma, struct proto_tag *parent,
535dcca8e8SMarcel Moolenaar     struct proto_ioc_busdma *ioc)
544f027abdSMarcel Moolenaar {
554f027abdSMarcel Moolenaar 	struct proto_tag *tag;
564f027abdSMarcel Moolenaar 
575dcca8e8SMarcel Moolenaar 	/*
585dcca8e8SMarcel Moolenaar 	 * If nsegs is 1, ignore maxsegsz. What this means is that if we have
595dcca8e8SMarcel Moolenaar 	 * just 1 segment, then maxsz should be equal to maxsegsz. To keep it
605dcca8e8SMarcel Moolenaar 	 * simple for us, limit maxsegsz to maxsz in any case.
615dcca8e8SMarcel Moolenaar 	 */
625dcca8e8SMarcel Moolenaar 	if (ioc->u.tag.maxsegsz > ioc->u.tag.maxsz || ioc->u.tag.nsegs == 1)
635dcca8e8SMarcel Moolenaar 		ioc->u.tag.maxsegsz = ioc->u.tag.maxsz;
645dcca8e8SMarcel Moolenaar 
655dcca8e8SMarcel Moolenaar 	/* A bndry of 0 really means ~0, or no boundary. */
665dcca8e8SMarcel Moolenaar 	if (ioc->u.tag.bndry == 0)
675dcca8e8SMarcel Moolenaar 		ioc->u.tag.bndry = ~0U;
684f027abdSMarcel Moolenaar 
694f027abdSMarcel Moolenaar 	tag = malloc(sizeof(*tag), M_PROTO_BUSDMA, M_WAITOK | M_ZERO);
705dcca8e8SMarcel Moolenaar 	if (parent != NULL) {
715dcca8e8SMarcel Moolenaar 		tag->parent = parent;
725dcca8e8SMarcel Moolenaar 		LIST_INSERT_HEAD(&parent->children, tag, peers);
735dcca8e8SMarcel Moolenaar 		tag->align = MAX(ioc->u.tag.align, parent->align);
745dcca8e8SMarcel Moolenaar 		tag->bndry = MIN(ioc->u.tag.bndry, parent->bndry);
755dcca8e8SMarcel Moolenaar 		tag->maxaddr = MIN(ioc->u.tag.maxaddr, parent->maxaddr);
765dcca8e8SMarcel Moolenaar 		tag->maxsz = MIN(ioc->u.tag.maxsz, parent->maxsz);
775dcca8e8SMarcel Moolenaar 		tag->maxsegsz = MIN(ioc->u.tag.maxsegsz, parent->maxsegsz);
785dcca8e8SMarcel Moolenaar 		tag->nsegs = MIN(ioc->u.tag.nsegs, parent->nsegs);
795dcca8e8SMarcel Moolenaar 		tag->datarate = MIN(ioc->u.tag.datarate, parent->datarate);
805dcca8e8SMarcel Moolenaar 		/* Write constraints back */
815dcca8e8SMarcel Moolenaar 		ioc->u.tag.align = tag->align;
825dcca8e8SMarcel Moolenaar 		ioc->u.tag.bndry = tag->bndry;
835dcca8e8SMarcel Moolenaar 		ioc->u.tag.maxaddr = tag->maxaddr;
845dcca8e8SMarcel Moolenaar 		ioc->u.tag.maxsz = tag->maxsz;
855dcca8e8SMarcel Moolenaar 		ioc->u.tag.maxsegsz = tag->maxsegsz;
865dcca8e8SMarcel Moolenaar 		ioc->u.tag.nsegs = tag->nsegs;
875dcca8e8SMarcel Moolenaar 		ioc->u.tag.datarate = tag->datarate;
885dcca8e8SMarcel Moolenaar 	} else {
895dcca8e8SMarcel Moolenaar 		tag->align = ioc->u.tag.align;
905dcca8e8SMarcel Moolenaar 		tag->bndry = ioc->u.tag.bndry;
915dcca8e8SMarcel Moolenaar 		tag->maxaddr = ioc->u.tag.maxaddr;
925dcca8e8SMarcel Moolenaar 		tag->maxsz = ioc->u.tag.maxsz;
935dcca8e8SMarcel Moolenaar 		tag->maxsegsz = ioc->u.tag.maxsegsz;
945dcca8e8SMarcel Moolenaar 		tag->nsegs = ioc->u.tag.nsegs;
955dcca8e8SMarcel Moolenaar 		tag->datarate = ioc->u.tag.datarate;
965dcca8e8SMarcel Moolenaar 	}
975dcca8e8SMarcel Moolenaar 	LIST_INSERT_HEAD(&busdma->tags, tag, tags);
985dcca8e8SMarcel Moolenaar 	ioc->result = (uintptr_t)(void *)tag;
994f027abdSMarcel Moolenaar 	return (0);
1004f027abdSMarcel Moolenaar }
1014f027abdSMarcel Moolenaar 
1025dcca8e8SMarcel Moolenaar static int
1035dcca8e8SMarcel Moolenaar proto_busdma_tag_destroy(struct proto_busdma *busdma, struct proto_tag *tag)
1044f027abdSMarcel Moolenaar {
1054f027abdSMarcel Moolenaar 
1065dcca8e8SMarcel Moolenaar 	if (!LIST_EMPTY(&tag->mds))
1075dcca8e8SMarcel Moolenaar 		return (EBUSY);
1085dcca8e8SMarcel Moolenaar 	if (!LIST_EMPTY(&tag->children))
1095dcca8e8SMarcel Moolenaar 		return (EBUSY);
1105dcca8e8SMarcel Moolenaar 
1115dcca8e8SMarcel Moolenaar 	if (tag->parent != NULL) {
1125dcca8e8SMarcel Moolenaar 		LIST_REMOVE(tag, peers);
1135dcca8e8SMarcel Moolenaar 		tag->parent = NULL;
1145dcca8e8SMarcel Moolenaar 	}
1155dcca8e8SMarcel Moolenaar 	LIST_REMOVE(tag, tags);
1164f027abdSMarcel Moolenaar 	free(tag, M_PROTO_BUSDMA);
1175dcca8e8SMarcel Moolenaar 	return (0);
1184f027abdSMarcel Moolenaar }
1194f027abdSMarcel Moolenaar 
1204f027abdSMarcel Moolenaar static struct proto_tag *
1214f027abdSMarcel Moolenaar proto_busdma_tag_lookup(struct proto_busdma *busdma, u_long key)
1224f027abdSMarcel Moolenaar {
1234f027abdSMarcel Moolenaar 	struct proto_tag *tag;
1244f027abdSMarcel Moolenaar 
1255dcca8e8SMarcel Moolenaar 	LIST_FOREACH(tag, &busdma->tags, tags) {
1264f027abdSMarcel Moolenaar 		if ((void *)tag == (void *)key)
1274f027abdSMarcel Moolenaar 			return (tag);
1284f027abdSMarcel Moolenaar 	}
1294f027abdSMarcel Moolenaar 	return (NULL);
1304f027abdSMarcel Moolenaar }
1314f027abdSMarcel Moolenaar 
132*90a1793cSMarcel Moolenaar static void
133*90a1793cSMarcel Moolenaar proto_busdma_mem_alloc_callback(void *arg, bus_dma_segment_t *segs, int	nseg,
134*90a1793cSMarcel Moolenaar     int error)
135*90a1793cSMarcel Moolenaar {
136*90a1793cSMarcel Moolenaar 	struct proto_ioc_busdma *ioc = arg;
137*90a1793cSMarcel Moolenaar 
138*90a1793cSMarcel Moolenaar 	ioc->u.mem.bus_nsegs = nseg;
139*90a1793cSMarcel Moolenaar 	ioc->u.mem.bus_addr = segs[0].ds_addr;
140*90a1793cSMarcel Moolenaar }
141*90a1793cSMarcel Moolenaar 
1425dcca8e8SMarcel Moolenaar static int
1435dcca8e8SMarcel Moolenaar proto_busdma_mem_alloc(struct proto_busdma *busdma, struct proto_tag *tag,
1445dcca8e8SMarcel Moolenaar     struct proto_ioc_busdma *ioc)
1455dcca8e8SMarcel Moolenaar {
1465dcca8e8SMarcel Moolenaar 	struct proto_md *md;
1475dcca8e8SMarcel Moolenaar 	int error;
1485dcca8e8SMarcel Moolenaar 
1495dcca8e8SMarcel Moolenaar 	md = malloc(sizeof(*md), M_PROTO_BUSDMA, M_WAITOK | M_ZERO);
1505dcca8e8SMarcel Moolenaar 	md->tag = tag;
1515dcca8e8SMarcel Moolenaar 
1525dcca8e8SMarcel Moolenaar 	error = bus_dma_tag_create(busdma->bd_roottag, tag->align, tag->bndry,
1535dcca8e8SMarcel Moolenaar 	    tag->maxaddr, BUS_SPACE_MAXADDR, NULL, NULL, tag->maxsz,
1545dcca8e8SMarcel Moolenaar 	    tag->nsegs, tag->maxsegsz, 0, NULL, NULL, &md->bd_tag);
1555dcca8e8SMarcel Moolenaar 	if (error) {
1565dcca8e8SMarcel Moolenaar 		free(md, M_PROTO_BUSDMA);
1575dcca8e8SMarcel Moolenaar 		return (error);
1585dcca8e8SMarcel Moolenaar 	}
159cff0f135SMarcel Moolenaar 	error = bus_dmamem_alloc(md->bd_tag, &md->virtaddr, 0, &md->bd_map);
1605dcca8e8SMarcel Moolenaar 	if (error) {
1615dcca8e8SMarcel Moolenaar 		bus_dma_tag_destroy(md->bd_tag);
1625dcca8e8SMarcel Moolenaar 		free(md, M_PROTO_BUSDMA);
1635dcca8e8SMarcel Moolenaar 		return (error);
1645dcca8e8SMarcel Moolenaar 	}
165cff0f135SMarcel Moolenaar 	md->physaddr = pmap_kextract((uintptr_t)(md->virtaddr));
166*90a1793cSMarcel Moolenaar 	error = bus_dmamap_load(md->bd_tag, md->bd_map, md->virtaddr,
167*90a1793cSMarcel Moolenaar 	    tag->maxsz, proto_busdma_mem_alloc_callback, ioc, BUS_DMA_NOWAIT);
168*90a1793cSMarcel Moolenaar 	if (error) {
169*90a1793cSMarcel Moolenaar 		bus_dmamem_free(md->bd_tag, md->virtaddr, md->bd_map);
170*90a1793cSMarcel Moolenaar 		bus_dma_tag_destroy(md->bd_tag);
171*90a1793cSMarcel Moolenaar 		free(md, M_PROTO_BUSDMA);
172*90a1793cSMarcel Moolenaar 		return (error);
173*90a1793cSMarcel Moolenaar 	}
1745dcca8e8SMarcel Moolenaar 	LIST_INSERT_HEAD(&tag->mds, md, peers);
1755dcca8e8SMarcel Moolenaar 	LIST_INSERT_HEAD(&busdma->mds, md, mds);
176*90a1793cSMarcel Moolenaar 	ioc->u.mem.phys_nsegs = 1;
177*90a1793cSMarcel Moolenaar 	ioc->u.mem.phys_addr = md->physaddr;
1785dcca8e8SMarcel Moolenaar 	ioc->result = (uintptr_t)(void *)md;
1795dcca8e8SMarcel Moolenaar 	return (0);
1805dcca8e8SMarcel Moolenaar }
1815dcca8e8SMarcel Moolenaar 
1825dcca8e8SMarcel Moolenaar static int
1835dcca8e8SMarcel Moolenaar proto_busdma_mem_free(struct proto_busdma *busdma, struct proto_md *md)
1845dcca8e8SMarcel Moolenaar {
1855dcca8e8SMarcel Moolenaar 
1865dcca8e8SMarcel Moolenaar 	LIST_REMOVE(md, mds);
1875dcca8e8SMarcel Moolenaar 	LIST_REMOVE(md, peers);
188cff0f135SMarcel Moolenaar 	bus_dmamem_free(md->bd_tag, md->virtaddr, md->bd_map);
1895dcca8e8SMarcel Moolenaar 	bus_dma_tag_destroy(md->bd_tag);
1905dcca8e8SMarcel Moolenaar 	free(md, M_PROTO_BUSDMA);
1915dcca8e8SMarcel Moolenaar 	return (0);
1925dcca8e8SMarcel Moolenaar }
1935dcca8e8SMarcel Moolenaar 
1945dcca8e8SMarcel Moolenaar static struct proto_md *
1955dcca8e8SMarcel Moolenaar proto_busdma_md_lookup(struct proto_busdma *busdma, u_long key)
1965dcca8e8SMarcel Moolenaar {
1975dcca8e8SMarcel Moolenaar 	struct proto_md *md;
1985dcca8e8SMarcel Moolenaar 
1995dcca8e8SMarcel Moolenaar 	LIST_FOREACH(md, &busdma->mds, mds) {
2005dcca8e8SMarcel Moolenaar 		if ((void *)md == (void *)key)
2015dcca8e8SMarcel Moolenaar 			return (md);
2025dcca8e8SMarcel Moolenaar 	}
2035dcca8e8SMarcel Moolenaar 	return (NULL);
2045dcca8e8SMarcel Moolenaar }
2055dcca8e8SMarcel Moolenaar 
2064f027abdSMarcel Moolenaar struct proto_busdma *
2074f027abdSMarcel Moolenaar proto_busdma_attach(struct proto_softc *sc)
2084f027abdSMarcel Moolenaar {
2094f027abdSMarcel Moolenaar 	struct proto_busdma *busdma;
2104f027abdSMarcel Moolenaar 
2114f027abdSMarcel Moolenaar 	busdma = malloc(sizeof(*busdma), M_PROTO_BUSDMA, M_WAITOK | M_ZERO);
2124f027abdSMarcel Moolenaar 	return (busdma);
2134f027abdSMarcel Moolenaar }
2144f027abdSMarcel Moolenaar 
2154f027abdSMarcel Moolenaar int
2164f027abdSMarcel Moolenaar proto_busdma_detach(struct proto_softc *sc, struct proto_busdma *busdma)
2174f027abdSMarcel Moolenaar {
2184f027abdSMarcel Moolenaar 
2194f027abdSMarcel Moolenaar 	proto_busdma_cleanup(sc, busdma);
2204f027abdSMarcel Moolenaar 	free(busdma, M_PROTO_BUSDMA);
2214f027abdSMarcel Moolenaar 	return (0);
2224f027abdSMarcel Moolenaar }
2234f027abdSMarcel Moolenaar 
2244f027abdSMarcel Moolenaar int
2254f027abdSMarcel Moolenaar proto_busdma_cleanup(struct proto_softc *sc, struct proto_busdma *busdma)
2264f027abdSMarcel Moolenaar {
2275dcca8e8SMarcel Moolenaar 	struct proto_md *md, *md1;
2284f027abdSMarcel Moolenaar 	struct proto_tag *tag, *tag1;
2294f027abdSMarcel Moolenaar 
2305dcca8e8SMarcel Moolenaar 	LIST_FOREACH_SAFE(md, &busdma->mds, mds, md1)
2315dcca8e8SMarcel Moolenaar 		proto_busdma_mem_free(busdma, md);
2325dcca8e8SMarcel Moolenaar 	LIST_FOREACH_SAFE(tag, &busdma->tags, tags, tag1)
2335dcca8e8SMarcel Moolenaar 		proto_busdma_tag_destroy(busdma, tag);
2344f027abdSMarcel Moolenaar 	return (0);
2354f027abdSMarcel Moolenaar }
2364f027abdSMarcel Moolenaar 
2374f027abdSMarcel Moolenaar int
2384f027abdSMarcel Moolenaar proto_busdma_ioctl(struct proto_softc *sc, struct proto_busdma *busdma,
2394f027abdSMarcel Moolenaar     struct proto_ioc_busdma *ioc)
2404f027abdSMarcel Moolenaar {
2414f027abdSMarcel Moolenaar 	struct proto_tag *tag;
2425dcca8e8SMarcel Moolenaar 	struct proto_md *md;
2434f027abdSMarcel Moolenaar 	int error;
2444f027abdSMarcel Moolenaar 
2454f027abdSMarcel Moolenaar 	error = 0;
2464f027abdSMarcel Moolenaar 	switch (ioc->request) {
2474f027abdSMarcel Moolenaar 	case PROTO_IOC_BUSDMA_TAG_CREATE:
2485dcca8e8SMarcel Moolenaar 		busdma->bd_roottag = bus_get_dma_tag(sc->sc_dev);
2495dcca8e8SMarcel Moolenaar 		error = proto_busdma_tag_create(busdma, NULL, ioc);
2504f027abdSMarcel Moolenaar 		break;
2514f027abdSMarcel Moolenaar 	case PROTO_IOC_BUSDMA_TAG_DERIVE:
2524f027abdSMarcel Moolenaar 		tag = proto_busdma_tag_lookup(busdma, ioc->key);
2534f027abdSMarcel Moolenaar 		if (tag == NULL) {
2544f027abdSMarcel Moolenaar 			error = EINVAL;
2554f027abdSMarcel Moolenaar 			break;
2564f027abdSMarcel Moolenaar 		}
2575dcca8e8SMarcel Moolenaar 		error = proto_busdma_tag_create(busdma, tag, ioc);
2584f027abdSMarcel Moolenaar 		break;
2594f027abdSMarcel Moolenaar 	case PROTO_IOC_BUSDMA_TAG_DESTROY:
2604f027abdSMarcel Moolenaar 		tag = proto_busdma_tag_lookup(busdma, ioc->key);
2614f027abdSMarcel Moolenaar 		if (tag == NULL) {
2624f027abdSMarcel Moolenaar 			error = EINVAL;
2634f027abdSMarcel Moolenaar 			break;
2644f027abdSMarcel Moolenaar 		}
2655dcca8e8SMarcel Moolenaar 		error = proto_busdma_tag_destroy(busdma, tag);
2665dcca8e8SMarcel Moolenaar 		break;
2675dcca8e8SMarcel Moolenaar 	case PROTO_IOC_BUSDMA_MEM_ALLOC:
2685dcca8e8SMarcel Moolenaar 		tag = proto_busdma_tag_lookup(busdma, ioc->u.mem.tag);
2695dcca8e8SMarcel Moolenaar 		if (tag == NULL) {
2705dcca8e8SMarcel Moolenaar 			error = EINVAL;
2715dcca8e8SMarcel Moolenaar 			break;
2725dcca8e8SMarcel Moolenaar 		}
2735dcca8e8SMarcel Moolenaar 		error = proto_busdma_mem_alloc(busdma, tag, ioc);
2745dcca8e8SMarcel Moolenaar 		break;
2755dcca8e8SMarcel Moolenaar 	case PROTO_IOC_BUSDMA_MEM_FREE:
2765dcca8e8SMarcel Moolenaar 		md = proto_busdma_md_lookup(busdma, ioc->key);
2775dcca8e8SMarcel Moolenaar 		if (md == NULL) {
2785dcca8e8SMarcel Moolenaar 			error = EINVAL;
2795dcca8e8SMarcel Moolenaar 			break;
2805dcca8e8SMarcel Moolenaar 		}
2815dcca8e8SMarcel Moolenaar 		error = proto_busdma_mem_free(busdma, md);
2824f027abdSMarcel Moolenaar 		break;
2834f027abdSMarcel Moolenaar 	default:
2844f027abdSMarcel Moolenaar 		error = EINVAL;
2854f027abdSMarcel Moolenaar 		break;
2864f027abdSMarcel Moolenaar 	}
2874f027abdSMarcel Moolenaar 	return (error);
2884f027abdSMarcel Moolenaar }
289cff0f135SMarcel Moolenaar 
290cff0f135SMarcel Moolenaar int
291cff0f135SMarcel Moolenaar proto_busdma_mmap_allowed(struct proto_busdma *busdma, vm_paddr_t physaddr)
292cff0f135SMarcel Moolenaar {
293cff0f135SMarcel Moolenaar 	struct proto_md *md;
294cff0f135SMarcel Moolenaar 
295cff0f135SMarcel Moolenaar 	LIST_FOREACH(md, &busdma->mds, mds) {
296cff0f135SMarcel Moolenaar 		if (physaddr >= trunc_page(md->physaddr) &&
297cff0f135SMarcel Moolenaar 		    physaddr <= trunc_page(md->physaddr + md->tag->maxsz))
298cff0f135SMarcel Moolenaar 			return (1);
299cff0f135SMarcel Moolenaar 	}
300cff0f135SMarcel Moolenaar 	return (0);
301cff0f135SMarcel Moolenaar }
302