xref: /netbsd/sys/arch/sun68k/sun68k/bus.c (revision 6550d01e)
1 /*	$NetBSD: bus.c,v 1.21 2008/06/04 12:41:41 ad Exp $	*/
2 
3 /*
4  * Copyright (c) 1982, 1986, 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * the Systems Programming Group of the University of Utah Computer
9  * Science Department.
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  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	from: Utah Hdr: machdep.c 1.74 92/12/20
36  *	from: @(#)machdep.c	8.10 (Berkeley) 4/20/94
37  */
38 
39 /*
40  * Copyright (c) 2001 Matthew Fredette.
41  * Copyright (c) 1994, 1995 Gordon W. Ross
42  * Copyright (c) 1993 Adam Glass
43  * Copyright (c) 1988 University of Utah.
44  *
45  * This code is derived from software contributed to Berkeley by
46  * the Systems Programming Group of the University of Utah Computer
47  * Science Department.
48  *
49  * Redistribution and use in source and binary forms, with or without
50  * modification, are permitted provided that the following conditions
51  * are met:
52  * 1. Redistributions of source code must retain the above copyright
53  *    notice, this list of conditions and the following disclaimer.
54  * 2. Redistributions in binary form must reproduce the above copyright
55  *    notice, this list of conditions and the following disclaimer in the
56  *    documentation and/or other materials provided with the distribution.
57  * 3. All advertising materials mentioning features or use of this software
58  *    must display the following acknowledgement:
59  *	This product includes software developed by the University of
60  *	California, Berkeley and its contributors.
61  * 4. Neither the name of the University nor the names of its contributors
62  *    may be used to endorse or promote products derived from this software
63  *    without specific prior written permission.
64  *
65  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
66  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
68  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
69  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
70  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
71  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
72  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
73  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
74  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
75  * SUCH DAMAGE.
76  *
77  *	from: Utah Hdr: machdep.c 1.74 92/12/20
78  *	from: @(#)machdep.c	8.10 (Berkeley) 4/20/94
79  */
80 
81 /*-
82  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
83  * All rights reserved.
84  *
85  * This code is derived from software contributed to The NetBSD Foundation
86  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
87  * NASA Ames Research Center.
88  *
89  * Redistribution and use in source and binary forms, with or without
90  * modification, are permitted provided that the following conditions
91  * are met:
92  * 1. Redistributions of source code must retain the above copyright
93  *    notice, this list of conditions and the following disclaimer.
94  * 2. Redistributions in binary form must reproduce the above copyright
95  *    notice, this list of conditions and the following disclaimer in the
96  *    documentation and/or other materials provided with the distribution.
97  *
98  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
99  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
100  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
101  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
102  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
103  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
104  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
105  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
106  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
107  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
108  * POSSIBILITY OF SUCH DAMAGE.
109  */
110 
111 /*
112  * Copyright (c) 1992, 1993
113  *	The Regents of the University of California.  All rights reserved.
114  *
115  * This software was developed by the Computer Systems Engineering group
116  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
117  * contributed to Berkeley.
118  *
119  * All advertising materials mentioning features or use of this software
120  * must display the following acknowledgement:
121  *	This product includes software developed by the University of
122  *	California, Lawrence Berkeley Laboratory.
123  *
124  * Redistribution and use in source and binary forms, with or without
125  * modification, are permitted provided that the following conditions
126  * are met:
127  * 1. Redistributions of source code must retain the above copyright
128  *    notice, this list of conditions and the following disclaimer.
129  * 2. Redistributions in binary form must reproduce the above copyright
130  *    notice, this list of conditions and the following disclaimer in the
131  *    documentation and/or other materials provided with the distribution.
132  * 3. All advertising materials mentioning features or use of this software
133  *    must display the following acknowledgement:
134  *	This product includes software developed by the University of
135  *	California, Berkeley and its contributors.
136  * 4. Neither the name of the University nor the names of its contributors
137  *    may be used to endorse or promote products derived from this software
138  *    without specific prior written permission.
139  *
140  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
141  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
142  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
143  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
144  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
145  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
146  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
147  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
148  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
149  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
150  * SUCH DAMAGE.
151  *
152  *	@(#)machdep.c	8.6 (Berkeley) 1/14/94
153  */
154 
155 #include <sys/cdefs.h>
156 __KERNEL_RCSID(0, "$NetBSD: bus.c,v 1.21 2008/06/04 12:41:41 ad Exp $");
157 
158 #include <sys/param.h>
159 #include <sys/systm.h>
160 #include <sys/kernel.h>
161 #include <sys/device.h>
162 #include <sys/malloc.h>
163 #include <sys/mbuf.h>
164 
165 #include <uvm/uvm.h> /* XXX: not _extern ... need vm_map_create */
166 
167 #include <machine/pte.h>
168 #define _SUN68K_BUS_DMA_PRIVATE
169 #include <machine/autoconf.h>
170 #include <machine/bus.h>
171 #include <machine/intr.h>
172 #include <machine/mon.h>
173 #include <machine/pmap.h>
174 
175 #include <sun68k/sun68k/control.h>
176 
177 /*
178  * Common function for DMA map creation.  May be called by bus-specific
179  * DMA map creation functions.
180  */
181 int
182 _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments,
183     bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
184 {
185 	struct sun68k_bus_dmamap *map;
186 	void *mapstore;
187 	size_t mapsize;
188 
189 	/*
190 	 * Allocate and initialize the DMA map.  The end of the map
191 	 * is a variable-sized array of segments, so we allocate enough
192 	 * room for them in one shot.
193 	 *
194 	 * Note we don't preserve the WAITOK or NOWAIT flags.  Preservation
195 	 * of ALLOCNOW notifies others that we've reserved these resources,
196 	 * and they are not to be freed.
197 	 *
198 	 * The bus_dmamap_t includes one bus_dma_segment_t, hence
199 	 * the (nsegments - 1).
200 	 */
201 	mapsize = sizeof(struct sun68k_bus_dmamap) +
202 	    (sizeof(bus_dma_segment_t) * (nsegments - 1));
203 	if ((mapstore = malloc(mapsize, M_DMAMAP,
204 	    (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL)
205 		return (ENOMEM);
206 
207 	memset(mapstore, 0, mapsize);
208 	map = (struct sun68k_bus_dmamap *)mapstore;
209 	map->_dm_size = size;
210 	map->_dm_segcnt = nsegments;
211 	map->_dm_maxmaxsegsz = maxsegsz;
212 	map->_dm_boundary = boundary;
213 	map->_dm_align = PAGE_SIZE;
214 	map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
215 	map->dm_maxsegsz = maxsegsz;
216 	map->dm_mapsize = 0;		/* no valid mappings */
217 	map->dm_nsegs = 0;
218 
219 	*dmamp = map;
220 	return (0);
221 }
222 
223 /*
224  * Common function for DMA map destruction.  May be called by bus-specific
225  * DMA map destruction functions.
226  */
227 void
228 _bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map)
229 {
230 
231 	/*
232 	 * If the handle contains a valid mapping, unload it.
233 	 */
234 	if (map->dm_mapsize != 0)
235 		bus_dmamap_unload(t, map);
236 
237 	free(map, M_DMAMAP);
238 }
239 
240 /*
241  * Common function for DMA-safe memory allocation.  May be called
242  * by bus-specific DMA memory allocation functions.
243  */
244 int
245 _bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
246     bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
247     int flags)
248 {
249 	vaddr_t low, high;
250 	struct pglist *mlist;
251 	int error;
252 extern	paddr_t avail_start;
253 extern	paddr_t avail_end;
254 
255 	/* Always round the size. */
256 	size = m68k_round_page(size);
257 	low = avail_start;
258 	high = avail_end;
259 
260 	if ((mlist = malloc(sizeof(*mlist), M_DEVBUF,
261 	    (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL)
262 		return (ENOMEM);
263 
264 	/*
265 	 * Allocate physical pages from the VM system.
266 	 */
267 	error = uvm_pglistalloc(size, low, high, 0, 0,
268 				mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0);
269 	if (error)
270 		return (error);
271 
272 	/*
273 	 * Simply keep a pointer around to the linked list, so
274 	 * bus_dmamap_free() can return it.
275 	 *
276 	 * NOBODY SHOULD TOUCH THE pageq.queue FIELDS WHILE THESE PAGES
277 	 * ARE IN OUR CUSTODY.
278 	 */
279 	segs[0]._ds_mlist = mlist;
280 
281 	/*
282 	 * We now have physical pages, but no DVMA addresses yet. These
283 	 * will be allocated in bus_dmamap_load*() routines. Hence we
284 	 * save any alignment and boundary requirements in this DMA
285 	 * segment.
286 	 */
287 	segs[0].ds_addr = 0;
288 	segs[0].ds_len = 0;
289 	segs[0]._ds_va = 0;
290 	*rsegs = 1;
291 	return (0);
292 }
293 
294 /*
295  * Common function for freeing DMA-safe memory.  May be called by
296  * bus-specific DMA memory free functions.
297  */
298 void
299 _bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs)
300 {
301 
302 	if (nsegs != 1)
303 		panic("bus_dmamem_free: nsegs = %d", nsegs);
304 
305 	/*
306 	 * Return the list of physical pages back to the VM system.
307 	 */
308 	uvm_pglistfree(segs[0]._ds_mlist);
309 	free(segs[0]._ds_mlist, M_DEVBUF);
310 }
311 
312 /*
313  * Common function for mapping DMA-safe memory.  May be called by
314  * bus-specific DMA memory map functions.
315  */
316 int
317 _bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
318     size_t size, void **kvap, int flags)
319 {
320 	struct vm_page *m;
321 	vaddr_t va;
322 	struct pglist *mlist;
323 	const uvm_flag_t kmflags =
324 	    (flags & BUS_DMA_NOWAIT) != 0 ? UVM_KMF_NOWAIT : 0;
325 
326 	if (nsegs != 1)
327 		panic("_bus_dmamem_map: nsegs = %d", nsegs);
328 
329 	size = m68k_round_page(size);
330 
331 	va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags);
332 	if (va == 0)
333 		return (ENOMEM);
334 
335 	segs[0]._ds_va = va;
336 	*kvap = (void *)va;
337 
338 	mlist = segs[0]._ds_mlist;
339 	for (m = TAILQ_FIRST(mlist); m != NULL; m = TAILQ_NEXT(m,pageq.queue)) {
340 		paddr_t pa;
341 
342 		if (size == 0)
343 			panic("_bus_dmamem_map: size botch");
344 
345 		pa = VM_PAGE_TO_PHYS(m);
346 		pmap_enter(pmap_kernel(), va, pa | PMAP_NC,
347 			   VM_PROT_READ | VM_PROT_WRITE,
348 			   VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED);
349 
350 		va += PAGE_SIZE;
351 		size -= PAGE_SIZE;
352 	}
353 	pmap_update(pmap_kernel());
354 
355 	return (0);
356 }
357 
358 /*
359  * Common function for unmapping DMA-safe memory.  May be called by
360  * bus-specific DMA memory unmapping functions.
361  */
362 void
363 _bus_dmamem_unmap(bus_dma_tag_t t, void *kva, size_t size)
364 {
365 
366 #ifdef DIAGNOSTIC
367 	if ((u_long)kva & PAGE_MASK)
368 		panic("_bus_dmamem_unmap");
369 #endif
370 
371 	size = m68k_round_page(size);
372 	uvm_unmap(kernel_map, (vaddr_t)kva, (vaddr_t)kva + size);
373 }
374 
375 /*
376  * Common functin for mmap(2)'ing DMA-safe memory.  May be called by
377  * bus-specific DMA mmap(2)'ing functions.
378  */
379 paddr_t
380 _bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, off_t off,
381     int prot, int flags)
382 {
383 
384 	panic("_bus_dmamem_mmap: not implemented");
385 }
386 
387 /*
388  * Utility to allocate an aligned kernel virtual address range
389  */
390 vaddr_t
391 _bus_dma_valloc_skewed(size_t size, u_long boundary, u_long align, u_long skew)
392 {
393 	vaddr_t va;
394 
395 	/*
396 	 * Find a region of kernel virtual addresses that is aligned
397 	 * to the given address modulo the requested alignment, i.e.
398 	 *
399 	 *	(va - skew) == 0 mod align
400 	 *
401 	 * The following conditions apply to the arguments:
402 	 *
403 	 *	- `size' must be a multiple of the VM page size
404 	 *	- `align' must be a power of two
405 	 *	   and greater than or equal to the VM page size
406 	 *	- `skew' must be smaller than `align'
407 	 *	- `size' must be smaller than `boundary'
408 	 */
409 
410 #ifdef DIAGNOSTIC
411 	if ((size & PAGE_MASK) != 0)
412 		panic("_bus_dma_valloc_skewed: invalid size %lx", (unsigned long) size);
413 	if ((align & PAGE_MASK) != 0)
414 		panic("_bus_dma_valloc_skewed: invalid alignment %lx", align);
415 	if (align < skew)
416 		panic("_bus_dma_valloc_skewed: align %lx < skew %lx",
417 			align, skew);
418 #endif
419 
420 	/* XXX - Implement this! */
421 	if (boundary || skew)
422 		panic("_bus_dma_valloc_skewed: not implemented");
423 
424 	/*
425 	 * First, find a region large enough to contain any aligned chunk
426 	 */
427 	va = uvm_km_alloc(kernel_map, size, align, UVM_KMF_VAONLY);
428 	if (va == 0)
429 		return (ENOMEM);
430 
431 	return (va);
432 }
433 
434 /*
435  * Like _bus_dmamap_load(), but for mbufs.
436  */
437 int
438 _bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m,
439     int flags)
440 {
441 
442 	panic("_bus_dmamap_load_mbuf: not implemented");
443 }
444 
445 /*
446  * Like _bus_dmamap_load(), but for uios.
447  */
448 int
449 _bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio,
450     int flags)
451 {
452 
453 	panic("_bus_dmamap_load_uio: not implemented");
454 }
455 
456 /*
457  * Common function for DMA map synchronization.  May be called
458  * by bus-specific DMA map synchronization functions.
459  */
460 void
461 _bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
462     bus_size_t len, int ops)
463 {
464 }
465 
466 struct sun68k_bus_dma_tag mainbus_dma_tag = {
467 	NULL,
468 	_bus_dmamap_create,
469 	_bus_dmamap_destroy,
470 	_bus_dmamap_load,
471 	_bus_dmamap_load_mbuf,
472 	_bus_dmamap_load_uio,
473 	_bus_dmamap_load_raw,
474 	_bus_dmamap_unload,
475 	_bus_dmamap_sync,
476 
477 	_bus_dmamem_alloc,
478 	_bus_dmamem_free,
479 	_bus_dmamem_map,
480 	_bus_dmamem_unmap,
481 	_bus_dmamem_mmap
482 };
483 
484 
485 /*
486  * Base bus space handlers.
487  */
488 static int	sun68k_bus_map(bus_space_tag_t, bus_type_t, bus_addr_t,
489 		    bus_size_t, int, vaddr_t, bus_space_handle_t *);
490 static int	sun68k_bus_unmap(bus_space_tag_t, bus_space_handle_t,
491 		    bus_size_t);
492 static int	sun68k_bus_subregion(bus_space_tag_t, bus_space_handle_t,
493 		    bus_size_t, bus_size_t, bus_space_handle_t *);
494 static paddr_t	sun68k_bus_mmap(bus_space_tag_t, bus_type_t, bus_addr_t, off_t,
495 		    int, int);
496 static void	*sun68k_mainbus_intr_establish(bus_space_tag_t, int, int, int,
497 		    int (*)(void *), void *);
498 static void	sun68k_bus_barrier(bus_space_tag_t, bus_space_handle_t,
499 		    bus_size_t, bus_size_t, int);
500 static int	sun68k_bus_peek(bus_space_tag_t, bus_space_handle_t,
501 		    bus_size_t, size_t, void *);
502 static int	sun68k_bus_poke(bus_space_tag_t, bus_space_handle_t,
503 		    bus_size_t, size_t, uint32_t);
504 
505 int
506 sun68k_bus_map(bus_space_tag_t t, bus_type_t iospace, bus_addr_t addr,
507     bus_size_t size, int flags, vaddr_t vaddr, bus_space_handle_t *hp)
508 {
509 	bus_size_t	offset;
510 	vaddr_t v;
511 
512 	/*
513 	 * If we suspect there might be one, try to find
514 	 * and use a PROM mapping.
515 	 */
516 	if ((flags & _SUN68K_BUS_MAP_USE_PROM) != 0 &&
517 	     find_prom_map(addr, iospace, size, &v) == 0) {
518 		*hp = (bus_space_handle_t)v;
519 		return (0);
520 	}
521 
522 	/*
523 	 * Adjust the user's request to be page-aligned.
524 	 */
525 	offset = addr & PGOFSET;
526 	addr -= offset;
527 	size += offset;
528 	size = m68k_round_page(size);
529 	if (size == 0) {
530 		printf("sun68k_bus_map: zero size\n");
531 		return (EINVAL);
532 	}
533 
534 	/* Get some kernel virtual address space. */
535 	if (vaddr)
536 		v = vaddr;
537 	else
538 		v = uvm_km_alloc(kernel_map, size, 0,
539 		    UVM_KMF_VAONLY | UVM_KMF_WAITVA);
540 	if (v == 0)
541 		panic("sun68k_bus_map: no memory");
542 
543 	/* note: preserve page offset */
544 	*hp = (bus_space_handle_t)(v | offset);
545 
546 	/*
547 	 * Map the device.
548 	 */
549 	addr |= iospace | PMAP_NC;
550 	pmap_map(v, addr, addr + size, VM_PROT_ALL);
551 
552 	return (0);
553 }
554 
555 int
556 sun68k_bus_unmap(bus_space_tag_t t, bus_space_handle_t bh, bus_size_t size)
557 {
558 	bus_size_t	offset;
559 	vaddr_t va = (vaddr_t)bh;
560 
561 	/*
562 	 * Adjust the user's request to be page-aligned.
563 	 */
564 	offset = va & PGOFSET;
565 	va -= offset;
566 	size += offset;
567 	size = m68k_round_page(size);
568 	if (size == 0) {
569 		printf("sun68k_bus_unmap: zero size\n");
570 		return (EINVAL);
571 	}
572 
573 	/*
574 	 * If any part of the request is in the PROM's address space,
575 	 * don't unmap it.
576 	 */
577 #ifdef	DIAGNOSTIC
578 	if ((va >= SUN_MONSTART && va < SUN_MONEND) !=
579 	    ((va + size) >= SUN_MONSTART && (va + size) < SUN_MONEND))
580 		panic("sun_bus_unmap: bad PROM mapping");
581 #endif
582 	if (va >= SUN_MONSTART && va < SUN_MONEND)
583 		return (0);
584 
585 	pmap_remove(pmap_kernel(), va, va + size);
586 	pmap_update(pmap_kernel());
587 	uvm_km_free(kernel_map, va, size, UVM_KMF_VAONLY);
588 	return (0);
589 }
590 
591 int
592 sun68k_bus_subregion(bus_space_tag_t tag, bus_space_handle_t handle,
593     bus_size_t offset, bus_size_t size, bus_space_handle_t *nhandlep)
594 {
595 
596 	*nhandlep = handle + offset;
597 	return (0);
598 }
599 
600 paddr_t
601 sun68k_bus_mmap(bus_space_tag_t t, bus_type_t iospace, bus_addr_t paddr,
602     off_t offset, int prot, int flags)
603 {
604 	paddr_t npaddr;
605 
606 	npaddr = m68k_trunc_page(paddr + offset);
607 	return (npaddr | (paddr_t)iospace | PMAP_NC);
608 }
609 
610 /*
611  * These assist in device probes.
612  */
613 
614 extern label_t *nofault;
615 
616 int
617 sun68k_bus_peek(bus_space_tag_t tag, bus_space_handle_t handle,
618     bus_size_t offset, size_t size, void *vp)
619 {
620 	int result;
621 	label_t	faultbuf;
622 	uint32_t junk;
623 
624 	if (vp == NULL)
625 		vp = &junk;
626 
627 	nofault = &faultbuf;
628 	if (setjmp(&faultbuf))
629 		result = -1;
630 	else {
631 		switch(size) {
632 		case 1:
633 			*((uint8_t *)vp) =
634 			    bus_space_read_1(tag, handle, offset);
635 			break;
636 		case 2:
637 			*((uint16_t *)vp) =
638 			    bus_space_read_2(tag, handle, offset);
639 			break;
640 		case 4:
641 			*((uint32_t *)vp) =
642 			    bus_space_read_4(tag, handle, offset);
643 			break;
644 		default:
645 			panic("_bus_space_peek: bad size");
646 		}
647 		result = 0;
648 	}
649 
650 	nofault = NULL;
651 	return (result);
652 }
653 
654 int
655 sun68k_bus_poke(bus_space_tag_t tag, bus_space_handle_t handle,
656     bus_size_t offset, size_t size, uint32_t v)
657 {
658 	int result;
659 	label_t	faultbuf;
660 
661 	nofault = &faultbuf;
662 	if (setjmp(&faultbuf))
663 		result = -1;
664 	else {
665 		switch(size) {
666 		case 1:
667 			bus_space_write_1(tag, handle, offset, (uint8_t)v);
668 			break;
669 		case 2:
670 			bus_space_write_2(tag, handle, offset, (uint16_t)v);
671 			break;
672 		case 4:
673 			bus_space_write_4(tag, handle, offset, (uint32_t)v);
674 			break;
675 		default:
676 			panic("_bus_space_poke: bad size");
677 		}
678 		result = 0;
679 	}
680 
681 	nofault = NULL;
682 	return (result);
683 }
684 
685 void *
686 sun68k_mainbus_intr_establish(bus_space_tag_t t, int pil, int level, int flags,
687     int (*handler)(void *), void *arg)
688 {
689 
690 	isr_add_autovect(handler, arg, pil);
691 	return (NULL);
692 }
693 
694 void
695 sun68k_bus_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset,
696     bus_size_t size, int flags)
697 {
698 
699 	/* No default barrier action defined */
700 	return;
701 }
702 
703 struct sun68k_bus_space_tag mainbus_space_tag = {
704 	NULL,				/* cookie */
705 	NULL,				/* parent bus tag */
706 	sun68k_bus_map,			/* bus_space_map */
707 	sun68k_bus_unmap,		/* bus_space_unmap */
708 	sun68k_bus_subregion,		/* bus_space_subregion */
709 	sun68k_bus_barrier,		/* bus_space_barrier */
710 	sun68k_bus_mmap,		/* bus_space_mmap */
711 	sun68k_mainbus_intr_establish,	/* bus_intr_establish */
712 	sun68k_bus_peek,		/* bus_space_peek_N */
713 	sun68k_bus_poke			/* bus_space_poke_N */
714 };
715