xref: /netbsd-src/sys/arch/sun2/include/bus.h (revision e55cffd8e520e9b03f18a1bd98bb04223e79f69f)
1 /*	$NetBSD: bus.h,v 1.2 2001/04/06 13:09:10 fredette Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996, 1997, 1998, 2001 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  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the NetBSD
22  *	Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 /*
41  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
42  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
43  *
44  * Redistribution and use in source and binary forms, with or without
45  * modification, are permitted provided that the following conditions
46  * are met:
47  * 1. Redistributions of source code must retain the above copyright
48  *    notice, this list of conditions and the following disclaimer.
49  * 2. Redistributions in binary form must reproduce the above copyright
50  *    notice, this list of conditions and the following disclaimer in the
51  *    documentation and/or other materials provided with the distribution.
52  * 3. All advertising materials mentioning features or use of this software
53  *    must display the following acknowledgement:
54  *      This product includes software developed by Christopher G. Demetriou
55  *	for the NetBSD Project.
56  * 4. The name of the author may not be used to endorse or promote products
57  *    derived from this software without specific prior written permission
58  *
59  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
60  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
61  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
62  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
63  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
64  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
65  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
66  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
67  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
68  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69  */
70 
71 #ifndef _SUN2_BUS_H_
72 #define _SUN2_BUS_H_
73 
74 #define	SUN2_BUS_SPACE	0
75 
76 /*
77  * Bus address and size types
78  */
79 typedef	u_long	bus_space_handle_t;
80 typedef u_long	bus_type_t;
81 typedef u_long	bus_addr_t;
82 typedef u_long	bus_size_t;
83 
84 /*
85  * Access methods for bus resources and address space.
86  */
87 typedef struct sun2_bus_space_tag	*bus_space_tag_t;
88 
89 struct sun2_bus_space_tag {
90 	void		*cookie;
91 	bus_space_tag_t	parent;
92 
93 	int	(*sun2_bus_map) __P((
94 				bus_space_tag_t,
95 				bus_type_t,
96 				bus_addr_t,
97 				bus_size_t,
98 				int,			/*flags*/
99 				vaddr_t,		/*preferred vaddr*/
100 				bus_space_handle_t *));
101 	int	(*sun2_bus_unmap) __P((
102 				bus_space_tag_t,
103 				bus_space_handle_t,
104 				bus_size_t));
105 	int	(*sun2_bus_subregion) __P((
106 				bus_space_tag_t,
107 				bus_space_handle_t,
108 				bus_size_t,		/*offset*/
109 				bus_size_t,		/*size*/
110 				bus_space_handle_t *));
111 
112 	void	(*sun2_bus_barrier) __P((
113 				bus_space_tag_t,
114 				bus_space_handle_t,
115 				bus_size_t,		/*offset*/
116 				bus_size_t,		/*size*/
117 				int));			/*flags*/
118 
119 	int	(*sun2_bus_mmap) __P((
120 				bus_space_tag_t,
121 				bus_type_t,		/**/
122 				bus_addr_t,		/**/
123 				int,			/*flags*/
124 				bus_space_handle_t *));
125 
126 	void	*(*sun2_intr_establish) __P((
127 				bus_space_tag_t,
128 				int,			/*bus-specific intr*/
129 				int,			/*device class level,
130 							  see machine/intr.h*/
131 				int,			/*flags*/
132 				int (*) __P((void *)),	/*handler*/
133 				void *));		/*handler arg*/
134 
135 };
136 
137 #if 0
138 /*
139  * The following macro could be used to generate the bus_space*() functions
140  * but it uses a gcc extension and is ANSI-only.
141 #define PROTO_bus_space_xxx		__P((bus_space_tag_t t, ...))
142 #define RETURNTYPE_bus_space_xxx	void *
143 #define BUSFUN(name, returntype, t, args...)			\
144 	__inline__ RETURNTYPE_##name				\
145 	bus_##name PROTO_##name					\
146 	{							\
147 		while (t->sun2_##name == NULL)			\
148 			t = t->parent;				\
149 		return (*(t)->sun2_##name)(t, args);		\
150 	}
151  */
152 #endif
153 
154 /*
155  * Bus space function prototypes.
156  */
157 static int	bus_space_map __P((
158 				bus_space_tag_t,
159 				bus_addr_t,
160 				bus_size_t,
161 				int,			/*flags*/
162 				bus_space_handle_t *));
163 static int	bus_space_map2 __P((
164 				bus_space_tag_t,
165 				bus_type_t,
166 				bus_addr_t,
167 				bus_size_t,
168 				int,			/*flags*/
169 				vaddr_t,		/*preferred vaddr*/
170 				bus_space_handle_t *));
171 static int	bus_space_unmap __P((
172 				bus_space_tag_t,
173 				bus_space_handle_t,
174 				bus_size_t));
175 static int	bus_space_subregion __P((
176 				bus_space_tag_t,
177 				bus_space_handle_t,
178 				bus_size_t,
179 				bus_size_t,
180 				bus_space_handle_t *));
181 static void	bus_space_barrier __P((
182 				bus_space_tag_t,
183 				bus_space_handle_t,
184 				bus_size_t,
185 				bus_size_t,
186 				int));
187 static int	bus_space_mmap __P((
188 				bus_space_tag_t,
189 				bus_type_t,		/**/
190 				bus_addr_t,		/**/
191 				int,			/*flags*/
192 				bus_space_handle_t *));
193 static void	*bus_intr_establish __P((
194 				bus_space_tag_t,
195 				int,			/*bus-specific intr*/
196 				int,			/*device class level,
197 							  see machine/intr.h*/
198 				int,			/*flags*/
199 				int (*) __P((void *)),	/*handler*/
200 				void *));		/*handler arg*/
201 
202 
203 /* This macro finds the first "upstream" implementation of method `f' */
204 #define _BS_CALL(t,f)			\
205 	while (t->f == NULL)		\
206 		t = t->parent;		\
207 	return (*(t)->f)
208 
209 __inline__ int
210 bus_space_map(t, a, s, f, hp)
211 	bus_space_tag_t	t;
212 	bus_addr_t	a;
213 	bus_size_t	s;
214 	int		f;
215 	bus_space_handle_t *hp;
216 {
217 	_BS_CALL(t, sun2_bus_map)((t), 0, (a), (s), (f), 0, (hp));
218 }
219 
220 __inline__ int
221 bus_space_map2(t, bt, a, s, f, v, hp)
222 	bus_space_tag_t	t;
223 	bus_type_t	bt;
224 	bus_addr_t	a;
225 	bus_size_t	s;
226 	int		f;
227 	vaddr_t		v;
228 	bus_space_handle_t *hp;
229 {
230 	_BS_CALL(t, sun2_bus_map)(t, bt, a, s, f, v, hp);
231 }
232 
233 __inline__ int
234 bus_space_unmap(t, h, s)
235 	bus_space_tag_t t;
236 	bus_space_handle_t h;
237 	bus_size_t	s;
238 {
239 	_BS_CALL(t, sun2_bus_unmap)(t, h, s);
240 }
241 
242 __inline__ int
243 bus_space_subregion(t, h, o, s, hp)
244 	bus_space_tag_t	t;
245 	bus_space_handle_t h;
246 	bus_size_t	o;
247 	bus_size_t	s;
248 	bus_space_handle_t *hp;
249 {
250 	_BS_CALL(t, sun2_bus_subregion)(t, h, o, s, hp);
251 }
252 
253 __inline__ int
254 bus_space_mmap(t, bt, a, f, hp)
255 	bus_space_tag_t	t;
256 	bus_type_t	bt;
257 	bus_addr_t	a;
258 	int		f;
259 	bus_space_handle_t *hp;
260 {
261 	_BS_CALL(t, sun2_bus_mmap)(t, bt, a, f, hp);
262 }
263 
264 __inline__ void *
265 bus_intr_establish(t, p, l, f, h, a)
266 	bus_space_tag_t t;
267 	int	p;
268 	int	l;
269 	int	f;
270 	int	(*h)__P((void *));
271 	void	*a;
272 {
273 	_BS_CALL(t, sun2_intr_establish)(t, p, l, f, h, a);
274 }
275 
276 __inline__ void
277 bus_space_barrier(t, h, o, s, f)
278 	bus_space_tag_t t;
279 	bus_space_handle_t h;
280 	bus_size_t o;
281 	bus_size_t s;
282 	int f;
283 {
284 	_BS_CALL(t, sun2_bus_barrier)(t, h, o, s, f);
285 }
286 
287 
288 #if 0
289 int	bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
290 	    bus_addr_t rend, bus_size_t size, bus_size_t align,
291 	    bus_size_t boundary, int flags, bus_addr_t *addrp,
292 	    bus_space_handle_t *bshp));
293 void	bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
294 	    bus_size_t size));
295 #endif
296 
297 /* flags for bus space map functions */
298 #define BUS_SPACE_MAP_CACHEABLE	0x0001
299 #define BUS_SPACE_MAP_LINEAR	0x0002
300 #define BUS_SPACE_MAP_PREFETCHABLE	0x0004
301 #define BUS_SPACE_MAP_BUS1	0x0100	/* placeholders for bus functions... */
302 #define BUS_SPACE_MAP_BUS2	0x0200
303 #define BUS_SPACE_MAP_BUS3	0x0400
304 #define BUS_SPACE_MAP_BUS4	0x0800
305 
306 /* Internal flag: try to find and use a PROM maping for the device. */
307 #define	_SUN2_BUS_MAP_USE_PROM		BUS_SPACE_MAP_BUS1
308 
309 /* flags for intr_establish() */
310 #define BUS_INTR_ESTABLISH_FASTTRAP	1
311 #define BUS_INTR_ESTABLISH_SOFTINTR	2
312 
313 /* flags for bus_space_barrier() */
314 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
315 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
316 
317 /*
318  * Device space probe assistant.
319  * The optional callback function's arguments are:
320  *	the temporary virtual address
321  *	the passed `arg' argument
322  */
323 int bus_space_probe __P((
324 		bus_space_tag_t,
325 		bus_type_t,
326 		bus_addr_t,
327 		bus_size_t,			/* probe size */
328 		size_t,				/* offset */
329 		int,				/* flags */
330 		int (*) __P((void *, void *)),	/* callback function */
331 		void *));			/* callback arg */
332 
333 
334 /*
335  *	u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
336  *	    bus_space_handle_t bsh, bus_size_t offset));
337  *
338  * Read a 1, 2, 4, or 8 byte quantity from bus space
339  * described by tag/handle/offset.
340  */
341 
342 #define	bus_space_read_1(t, h, o)					\
343 	    ((void)t, *(volatile u_int8_t *)((h) + (o)))
344 
345 #define	bus_space_read_2(t, h, o)					\
346 	    ((void)t, *(volatile u_int16_t *)((h) + (o)))
347 
348 #define	bus_space_read_4(t, h, o)					\
349 	    ((void)t, *(volatile u_int32_t *)((h) + (o)))
350 
351 #define	bus_space_read_8(t, h, o)					\
352 	    ((void)t, *(volatile u_int64_t *)((h) + (o)))
353 
354 
355 /*
356  *	void bus_space_write_N __P((bus_space_tag_t tag,
357  *	    bus_space_handle_t bsh, bus_size_t offset,
358  *	    u_intN_t value));
359  *
360  * Write the 1, 2, 4, or 8 byte value `value' to bus space
361  * described by tag/handle/offset.
362  */
363 
364 #define	bus_space_write_1(t, h, o, v)	do {				\
365 	((void)t, (void)(*(volatile u_int8_t *)((h) + (o)) = (v)));	\
366 } while (0)
367 
368 #define	bus_space_write_2(t, h, o, v)	do {				\
369 	((void)t, (void)(*(volatile u_int16_t *)((h) + (o)) = (v)));	\
370 } while (0)
371 
372 #define	bus_space_write_4(t, h, o, v)	do {				\
373 	((void)t, (void)(*(volatile u_int32_t *)((h) + (o)) = (v)));	\
374 } while (0)
375 
376 #define	bus_space_write_8(t, h, o, v)	do {				\
377 	((void)t, (void)(*(volatile u_int64_t *)((h) + (o)) = (v)));	\
378 } while (0)
379 
380 
381 /*
382  *	void bus_space_read_multi_N __P((bus_space_tag_t tag,
383  *	    bus_space_handle_t bsh, bus_size_t offset,
384  *	    u_intN_t *addr, bus_size_t count));
385  *
386  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
387  * described by tag/handle/offset and copy into buffer provided.
388  */
389 
390 void bus_space_read_multi_1 __P((bus_space_tag_t,
391 				 bus_space_handle_t,
392 				 bus_size_t,
393 				 u_int8_t *,
394 				 bus_size_t));
395 
396 void bus_space_read_multi_2 __P((bus_space_tag_t,
397 				 bus_space_handle_t,
398 				 bus_size_t,
399 				 u_int16_t *,
400 				 bus_size_t));
401 
402 void bus_space_read_multi_4 __P((bus_space_tag_t,
403 				 bus_space_handle_t,
404 				 bus_size_t,
405 				 u_int32_t *,
406 				 bus_size_t));
407 
408 void bus_space_read_multi_8 __P((bus_space_tag_t,
409 				 bus_space_handle_t,
410 				 bus_size_t,
411 				 u_int64_t *,
412 				 bus_size_t));
413 
414 extern __inline__ void
415 bus_space_read_multi_1(t, h, o, a, c)
416 	bus_space_tag_t		t;
417 	bus_space_handle_t	h;
418 	bus_size_t		o, c;
419 	u_int8_t		*a;
420 {
421 	while (c-- > 0)
422 		*a++ = bus_space_read_1(t, h, o);
423 }
424 
425 extern __inline__ void
426 bus_space_read_multi_2(t, h, o, a, c)
427 	bus_space_tag_t		t;
428 	bus_space_handle_t	h;
429 	bus_size_t		o, c;
430 	u_int16_t		*a;
431 {
432 	while (c-- > 0)
433 		*a++ = bus_space_read_2(t, h, o);
434 }
435 
436 extern __inline__ void
437 bus_space_read_multi_4(t, h, o, a, c)
438 	bus_space_tag_t		t;
439 	bus_space_handle_t	h;
440 	bus_size_t		o, c;
441 	u_int32_t		*a;
442 {
443 	while (c-- > 0)
444 		*a++ = bus_space_read_4(t, h, o);
445 }
446 
447 extern __inline__ void
448 bus_space_read_multi_8(t, h, o, a, c)
449 	bus_space_tag_t		t;
450 	bus_space_handle_t	h;
451 	bus_size_t		o, c;
452 	u_int64_t		*a;
453 {
454 	while (c-- > 0)
455 		*a++ = bus_space_read_8(t, h, o);
456 }
457 
458 
459 /*
460  *	void bus_space_write_multi_N __P((bus_space_tag_t tag,
461  *	    bus_space_handle_t bsh, bus_size_t offset,
462  *	    const u_intN_t *addr, bus_size_t count));
463  *
464  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
465  * provided to bus space described by tag/handle/offset.
466  */
467 void bus_space_write_multi_1 __P((bus_space_tag_t,
468 				  bus_space_handle_t,
469 				  bus_size_t,
470 				  const u_int8_t *,
471 				  bus_size_t));
472 void bus_space_write_multi_2 __P((bus_space_tag_t,
473 				  bus_space_handle_t,
474 				  bus_size_t,
475 				  const u_int16_t *,
476 				  bus_size_t));
477 void bus_space_write_multi_4 __P((bus_space_tag_t,
478 				  bus_space_handle_t,
479 				  bus_size_t,
480 				  const u_int32_t *,
481 				  bus_size_t));
482 void bus_space_write_multi_8 __P((bus_space_tag_t,
483 				  bus_space_handle_t,
484 				  bus_size_t,
485 				  const u_int64_t *,
486 				  bus_size_t));
487 extern __inline__ void
488 bus_space_write_multi_1(t, h, o, a, c)
489 	bus_space_tag_t		t;
490 	bus_space_handle_t	h;
491 	bus_size_t		o, c;
492 	const u_int8_t		*a;
493 {
494 	while (c-- > 0)
495 		bus_space_write_1(t, h, o, *a++);
496 }
497 
498 extern __inline__ void
499 bus_space_write_multi_2(t, h, o, a, c)
500 	bus_space_tag_t		t;
501 	bus_space_handle_t	h;
502 	bus_size_t		o, c;
503 	const u_int16_t		*a;
504 {
505 	while (c-- > 0)
506 		bus_space_write_2(t, h, o, *a++);
507 }
508 
509 extern __inline__ void
510 bus_space_write_multi_4(t, h, o, a, c)
511 	bus_space_tag_t		t;
512 	bus_space_handle_t	h;
513 	bus_size_t		o, c;
514 	const u_int32_t		*a;
515 {
516 	while (c-- > 0)
517 		bus_space_write_4(t, h, o, *a++);
518 }
519 
520 extern __inline__ void
521 bus_space_write_multi_8(t, h, o, a, c)
522 	bus_space_tag_t		t;
523 	bus_space_handle_t	h;
524 	bus_size_t		o, c;
525 	const u_int64_t		*a;
526 {
527 	while (c-- > 0)
528 		bus_space_write_8(t, h, o, *a++);
529 }
530 
531 /*
532  *	void bus_space_set_multi_N __P((bus_space_tag_t tag,
533  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
534  *	    bus_size_t count));
535  *
536  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
537  * by tag/handle/offset `count' times.
538  */
539 void bus_space_set_multi_1 __P((bus_space_tag_t,
540 				bus_space_handle_t,
541 				bus_size_t,
542 				const u_int8_t,
543 				bus_size_t));
544 void bus_space_set_multi_2 __P((bus_space_tag_t,
545 				bus_space_handle_t,
546 				bus_size_t,
547 				const u_int16_t,
548 				bus_size_t));
549 void bus_space_set_multi_4 __P((bus_space_tag_t,
550 				bus_space_handle_t,
551 				bus_size_t,
552 				const u_int32_t,
553 				bus_size_t));
554 void bus_space_set_multi_8 __P((bus_space_tag_t,
555 				bus_space_handle_t,
556 				bus_size_t,
557 				const u_int64_t,
558 				bus_size_t));
559 
560 extern __inline__ void
561 bus_space_set_multi_1(t, h, o, v, c)
562 	bus_space_tag_t		t;
563 	bus_space_handle_t	h;
564 	bus_size_t		o, c;
565 	const u_int8_t		v;
566 {
567 	while (c-- > 0)
568 		bus_space_write_1(t, h, o, v);
569 }
570 
571 extern __inline__ void
572 bus_space_set_multi_2(t, h, o, v, c)
573 	bus_space_tag_t		t;
574 	bus_space_handle_t	h;
575 	bus_size_t		o, c;
576 	const u_int16_t		v;
577 {
578 	while (c-- > 0)
579 		bus_space_write_2(t, h, o, v);
580 }
581 
582 extern __inline__ void
583 bus_space_set_multi_4(t, h, o, v, c)
584 	bus_space_tag_t		t;
585 	bus_space_handle_t	h;
586 	bus_size_t		o, c;
587 	const u_int32_t		v;
588 {
589 	while (c-- > 0)
590 		bus_space_write_4(t, h, o, v);
591 }
592 
593 extern __inline__ void
594 bus_space_set_multi_8(t, h, o, v, c)
595 	bus_space_tag_t		t;
596 	bus_space_handle_t	h;
597 	bus_size_t		o, c;
598 	const u_int64_t		v;
599 {
600 	while (c-- > 0)
601 		bus_space_write_8(t, h, o, v);
602 }
603 
604 
605 /*
606  *	void bus_space_read_region_N __P((bus_space_tag_t tag,
607  *	    bus_space_handle_t bsh, bus_size_t off,
608  *	    u_intN_t *addr, bus_size_t count));
609  *
610  */
611 void bus_space_read_region_1 __P((bus_space_tag_t,
612 				  bus_space_handle_t,
613 				  bus_size_t,
614 				  u_int8_t *,
615 				  bus_size_t));
616 void bus_space_read_region_2 __P((bus_space_tag_t,
617 				  bus_space_handle_t,
618 				  bus_size_t,
619 				  u_int16_t *,
620 				  bus_size_t));
621 void bus_space_read_region_4 __P((bus_space_tag_t,
622 				  bus_space_handle_t,
623 				  bus_size_t,
624 				  u_int32_t *,
625 				  bus_size_t));
626 void bus_space_read_region_8 __P((bus_space_tag_t,
627 				  bus_space_handle_t,
628 				  bus_size_t,
629 				  u_int64_t *,
630 				  bus_size_t));
631 
632 extern __inline__ void
633 bus_space_read_region_1(t, h, o, a, c)
634 	bus_space_tag_t		t;
635 	bus_space_handle_t	h;
636 	bus_size_t		o, c;
637 	u_int8_t		*a;
638 {
639 	for (; c; a++, c--, o++)
640 		*a = bus_space_read_1(t, h, o);
641 }
642 extern __inline__ void
643 bus_space_read_region_2(t, h, o, a, c)
644 	bus_space_tag_t		t;
645 	bus_space_handle_t	h;
646 	bus_size_t		o, c;
647 	u_int16_t		*a;
648 {
649 	for (; c; a++, c--, o+=2)
650 		*a = bus_space_read_2(t, h, o);
651 }
652 extern __inline__ void
653 bus_space_read_region_4(t, h, o, a, c)
654 	bus_space_tag_t		t;
655 	bus_space_handle_t	h;
656 	bus_size_t		o, c;
657 	u_int32_t		*a;
658 {
659 	for (; c; a++, c--, o+=4)
660 		*a = bus_space_read_4(t, h, o);
661 }
662 extern __inline__ void
663 bus_space_read_region_8(t, h, o, a, c)
664 	bus_space_tag_t		t;
665 	bus_space_handle_t	h;
666 	bus_size_t		o, c;
667 	u_int64_t		*a;
668 {
669 	for (; c; a++, c--, o+=8)
670 		*a = bus_space_read_8(t, h, o);
671 }
672 
673 /*
674  *	void bus_space_write_region_N __P((bus_space_tag_t tag,
675  *	    bus_space_handle_t bsh, bus_size_t off,
676  *	    u_intN_t *addr, bus_size_t count));
677  *
678  */
679 void bus_space_write_region_1 __P((bus_space_tag_t,
680 				   bus_space_handle_t,
681 				   bus_size_t,
682 				   const u_int8_t *,
683 				   bus_size_t));
684 void bus_space_write_region_2 __P((bus_space_tag_t,
685 				   bus_space_handle_t,
686 				   bus_size_t,
687 				   const u_int16_t *,
688 				   bus_size_t));
689 void bus_space_write_region_4 __P((bus_space_tag_t,
690 				   bus_space_handle_t,
691 				   bus_size_t,
692 				   const u_int32_t *,
693 				   bus_size_t));
694 void bus_space_write_region_8 __P((bus_space_tag_t,
695 				   bus_space_handle_t,
696 				   bus_size_t,
697 				   const u_int64_t *,
698 				   bus_size_t));
699 extern __inline__ void
700 bus_space_write_region_1(t, h, o, a, c)
701 	bus_space_tag_t		t;
702 	bus_space_handle_t	h;
703 	bus_size_t		o, c;
704 	const u_int8_t		*a;
705 {
706 	for (; c; a++, c--, o++)
707 		bus_space_write_1(t, h, o, *a);
708 }
709 
710 extern __inline__ void
711 bus_space_write_region_2(t, h, o, a, c)
712 	bus_space_tag_t		t;
713 	bus_space_handle_t	h;
714 	bus_size_t		o, c;
715 	const u_int16_t		*a;
716 {
717 	for (; c; a++, c--, o+=2)
718 		bus_space_write_2(t, h, o, *a);
719 }
720 
721 extern __inline__ void
722 bus_space_write_region_4(t, h, o, a, c)
723 	bus_space_tag_t		t;
724 	bus_space_handle_t	h;
725 	bus_size_t		o, c;
726 	const u_int32_t		*a;
727 {
728 	for (; c; a++, c--, o+=4)
729 		bus_space_write_4(t, h, o, *a);
730 }
731 
732 extern __inline__ void
733 bus_space_write_region_8(t, h, o, a, c)
734 	bus_space_tag_t		t;
735 	bus_space_handle_t	h;
736 	bus_size_t		o, c;
737 	const u_int64_t		*a;
738 {
739 	for (; c; a++, c--, o+=8)
740 		bus_space_write_8(t, h, o, *a);
741 }
742 
743 
744 /*
745  *	void bus_space_set_region_N __P((bus_space_tag_t tag,
746  *	    bus_space_handle_t bsh, bus_size_t off,
747  *	    u_intN_t *addr, bus_size_t count));
748  *
749  */
750 void bus_space_set_region_1 __P((bus_space_tag_t,
751 				 bus_space_handle_t,
752 				 bus_size_t,
753 				 const u_int8_t,
754 				 bus_size_t));
755 void bus_space_set_region_2 __P((bus_space_tag_t,
756 				 bus_space_handle_t,
757 				 bus_size_t,
758 				 const u_int16_t,
759 				 bus_size_t));
760 void bus_space_set_region_4 __P((bus_space_tag_t,
761 				 bus_space_handle_t,
762 				 bus_size_t,
763 				 const u_int32_t,
764 				 bus_size_t));
765 void bus_space_set_region_8 __P((bus_space_tag_t,
766 				 bus_space_handle_t,
767 				 bus_size_t,
768 				 const u_int64_t,
769 				 bus_size_t));
770 
771 extern __inline__ void
772 bus_space_set_region_1(t, h, o, v, c)
773 	bus_space_tag_t		t;
774 	bus_space_handle_t	h;
775 	bus_size_t		o, c;
776 	const u_int8_t		v;
777 {
778 	for (; c; c--, o++)
779 		bus_space_write_1(t, h, o, v);
780 }
781 
782 extern __inline__ void
783 bus_space_set_region_2(t, h, o, v, c)
784 	bus_space_tag_t		t;
785 	bus_space_handle_t	h;
786 	bus_size_t		o, c;
787 	const u_int16_t		v;
788 {
789 	for (; c; c--, o+=2)
790 		bus_space_write_2(t, h, o, v);
791 }
792 
793 extern __inline__ void
794 bus_space_set_region_4(t, h, o, v, c)
795 	bus_space_tag_t		t;
796 	bus_space_handle_t	h;
797 	bus_size_t		o, c;
798 	const u_int32_t		v;
799 {
800 	for (; c; c--, o+=4)
801 		bus_space_write_4(t, h, o, v);
802 }
803 
804 extern __inline__ void
805 bus_space_set_region_8(t, h, o, v, c)
806 	bus_space_tag_t		t;
807 	bus_space_handle_t	h;
808 	bus_size_t		o, c;
809 	const u_int64_t		v;
810 {
811 	for (; c; c--, o+=8)
812 		bus_space_write_8(t, h, o, v);
813 }
814 
815 
816 /*
817  *	void bus_space_copy_region_N __P((bus_space_tag_t tag,
818  *	    bus_space_handle_t bsh1, bus_size_t off1,
819  *	    bus_space_handle_t bsh2, bus_size_t off2,
820  *	    bus_size_t count));
821  *
822  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
823  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
824  */
825 void bus_space_copy_region_1 __P((bus_space_tag_t,
826 				  bus_space_handle_t,
827 				  bus_size_t,
828 				  bus_space_handle_t,
829 				  bus_size_t,
830 				  bus_size_t));
831 void bus_space_copy_region_2 __P((bus_space_tag_t,
832 				  bus_space_handle_t,
833 				  bus_size_t,
834 				  bus_space_handle_t,
835 				  bus_size_t,
836 				  bus_size_t));
837 void bus_space_copy_region_4 __P((bus_space_tag_t,
838 				  bus_space_handle_t,
839 				  bus_size_t,
840 				  bus_space_handle_t,
841 				  bus_size_t,
842 				  bus_size_t));
843 void bus_space_copy_region_8 __P((bus_space_tag_t,
844 				  bus_space_handle_t,
845 				  bus_size_t,
846 				  bus_space_handle_t,
847 				  bus_size_t,
848 				  bus_size_t));
849 
850 
851 extern __inline__ void
852 bus_space_copy_region_1(t, h1, o1, h2, o2, c)
853 	bus_space_tag_t		t;
854 	bus_space_handle_t	h1, h2;
855 	bus_size_t		o1, o2;
856 	bus_size_t		c;
857 {
858 	for (; c; c--, o1++, o2++)
859 	    bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2));
860 }
861 
862 extern __inline__ void
863 bus_space_copy_region_2(t, h1, o1, h2, o2, c)
864 	bus_space_tag_t		t;
865 	bus_space_handle_t	h1, h2;
866 	bus_size_t		o1, o2;
867 	bus_size_t		c;
868 {
869 	for (; c; c--, o1+=2, o2+=2)
870 	    bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2));
871 }
872 
873 extern __inline__ void
874 bus_space_copy_region_4(t, h1, o1, h2, o2, c)
875 	bus_space_tag_t		t;
876 	bus_space_handle_t	h1, h2;
877 	bus_size_t		o1, o2;
878 	bus_size_t		c;
879 {
880 	for (; c; c--, o1+=4, o2+=4)
881 	    bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2));
882 }
883 
884 extern __inline__ void
885 bus_space_copy_region_8(t, h1, o1, h2, o2, c)
886 	bus_space_tag_t		t;
887 	bus_space_handle_t	h1, h2;
888 	bus_size_t		o1, o2;
889 	bus_size_t		c;
890 {
891 	for (; c; c--, o1+=8, o2+=8)
892 	    bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2));
893 }
894 
895 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
896 
897 /*--------------------------------*/
898 
899 /*
900  * Flags used in various bus DMA methods.
901  */
902 #define	BUS_DMA_WAITOK		0x00	/* safe to sleep (pseudo-flag) */
903 #define	BUS_DMA_NOWAIT		0x01	/* not safe to sleep */
904 #define	BUS_DMA_ALLOCNOW	0x02	/* perform resource allocation now */
905 #define	BUS_DMA_COHERENT	0x04	/* hint: map memory DMA coherent */
906 #define	BUS_DMA_BUS1		0x10	/* placeholders for bus functions... */
907 #define	BUS_DMA_BUS2		0x20
908 #define	BUS_DMA_BUS3		0x40
909 #define	BUS_DMA_BUS4		0x80
910 
911 /* For devices that have a 24-bit address space */
912 #define BUS_DMA_24BIT		BUS_DMA_BUS1
913 
914 /* Internal flag: current DVMA address is equal to the KVA buffer address */
915 #define _BUS_DMA_DIRECTMAP	BUS_DMA_BUS2
916 
917 /*
918  * Internal flag: current DVMA address has been double-mapped by hand
919  * to the KVA buffer address (without the pmap's help).
920  */
921 #define	_BUS_DMA_NOPMAP		BUS_DMA_BUS3
922 
923 /* Forwards needed by prototypes below. */
924 struct mbuf;
925 struct uio;
926 
927 /*
928  * Operations performed by bus_dmamap_sync().
929  */
930 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
931 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
932 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
933 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
934 
935 typedef struct sun2_bus_dma_tag	*bus_dma_tag_t;
936 typedef struct sun2_bus_dmamap		*bus_dmamap_t;
937 
938 /*
939  *	bus_dma_segment_t
940  *
941  *	Describes a single contiguous DMA transaction.  Values
942  *	are suitable for programming into DMA registers.
943  */
944 struct sun2_bus_dma_segment {
945 	bus_addr_t	ds_addr;	/* DVMA address */
946 	bus_size_t	ds_len;		/* length of transfer */
947 	bus_size_t	_ds_sgsize;	/* size of allocated DVMA segment */
948 	void		*_ds_mlist;	/* page list when dmamem_alloc'ed */
949 	vaddr_t		_ds_va;		/* VA when dmamem_map'ed */
950 };
951 typedef struct sun2_bus_dma_segment	bus_dma_segment_t;
952 
953 
954 /*
955  *	bus_dma_tag_t
956  *
957  *	A machine-dependent opaque type describing the implementation of
958  *	DMA for a given bus.
959  */
960 struct sun2_bus_dma_tag {
961 	void	*_cookie;		/* cookie used in the guts */
962 
963 	/*
964 	 * DMA mapping methods.
965 	 */
966 	int	(*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
967 		    bus_size_t, bus_size_t, int, bus_dmamap_t *));
968 	void	(*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
969 	int	(*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
970 		    bus_size_t, struct proc *, int));
971 	int	(*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
972 		    struct mbuf *, int));
973 	int	(*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
974 		    struct uio *, int));
975 	int	(*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
976 		    bus_dma_segment_t *, int, bus_size_t, int));
977 	void	(*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
978 	void	(*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
979 		    bus_addr_t, bus_size_t, int));
980 
981 	/*
982 	 * DMA memory utility functions.
983 	 */
984 	int	(*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
985 		    bus_size_t, bus_dma_segment_t *, int, int *, int));
986 	void	(*_dmamem_free) __P((bus_dma_tag_t,
987 		    bus_dma_segment_t *, int));
988 	int	(*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
989 		    int, size_t, caddr_t *, int));
990 	void	(*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
991 	paddr_t	(*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
992 		    int, off_t, int, int));
993 };
994 
995 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
996 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
997 #define	bus_dmamap_destroy(t, p)				\
998 	(*(t)->_dmamap_destroy)((t), (p))
999 #define	bus_dmamap_load(t, m, b, s, p, f)			\
1000 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
1001 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
1002 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
1003 #define	bus_dmamap_load_uio(t, m, u, f)				\
1004 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
1005 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
1006 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
1007 #define	bus_dmamap_unload(t, p)					\
1008 	(*(t)->_dmamap_unload)((t), (p))
1009 #define	bus_dmamap_sync(t, p, o, l, ops)			\
1010 	(void)((t)->_dmamap_sync ?				\
1011 	    (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
1012 
1013 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
1014 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
1015 #define	bus_dmamem_free(t, sg, n)				\
1016 	(*(t)->_dmamem_free)((t), (sg), (n))
1017 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
1018 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
1019 #define	bus_dmamem_unmap(t, k, s)				\
1020 	(*(t)->_dmamem_unmap)((t), (k), (s))
1021 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
1022 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
1023 
1024 /*
1025  *	bus_dmamap_t
1026  *
1027  *	Describes a DMA mapping.
1028  */
1029 struct sun2_bus_dmamap {
1030 	/*
1031 	 * PRIVATE MEMBERS: not for use by machine-independent code.
1032 	 */
1033 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
1034 	int		_dm_segcnt;	/* number of segs this map can map */
1035 	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
1036 	bus_size_t	_dm_boundary;	/* don't cross this */
1037 	int		_dm_flags;	/* misc. flags */
1038 
1039 	void		*_dm_cookie;	/* cookie for bus-specific functions */
1040 
1041 	u_long		_dm_align;	/* DVMA alignment; must be a
1042 					   multiple of the page size */
1043 	u_long		_dm_ex_start;	/* constraints on DVMA map */
1044 	u_long		_dm_ex_end;	/* allocations; used by the VME bus
1045 					   driver and by the IOMMU driver
1046 					   when mapping 24-bit devices */
1047 
1048 	/*
1049 	 * PUBLIC MEMBERS: these are used by machine-independent code.
1050 	 */
1051 	bus_size_t	dm_mapsize;	/* size of the mapping */
1052 	int		dm_nsegs;	/* # valid segments in mapping */
1053 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
1054 };
1055 
1056 #ifdef _SUN2_BUS_DMA_PRIVATE
1057 int	_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
1058 	    bus_size_t, int, bus_dmamap_t *));
1059 void	_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
1060 int	_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
1061 	    struct mbuf *, int));
1062 int	_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
1063 	    struct uio *, int));
1064 int	_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
1065 	    bus_dma_segment_t *, int, bus_size_t, int));
1066 int	_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
1067 				bus_size_t, struct proc *, int));
1068 void	_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
1069 void	_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
1070 	    bus_size_t, int));
1071 
1072 int	_bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
1073 	    bus_size_t alignment, bus_size_t boundary,
1074 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
1075 void	_bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1076 	    int nsegs));
1077 int	_bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1078 				int nsegs, size_t size, caddr_t *kvap,
1079 				int flags));
1080 void	_bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
1081 	    size_t size));
1082 paddr_t	_bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1083 	    int nsegs, off_t off, int prot, int flags));
1084 
1085 int	_bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
1086 	    bus_size_t alignment, bus_size_t boundary,
1087 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
1088 	    vaddr_t low, vaddr_t high));
1089 
1090 vaddr_t	_bus_dma_valloc_skewed(size_t, u_long, u_long, u_long);
1091 #endif /* _SUN2_BUS_DMA_PRIVATE */
1092 
1093 #endif /* _SUN2_BUS_H_ */
1094