xref: /openbsd/sys/arch/sparc64/include/bus.h (revision af3f3b5c)
1 /*	$OpenBSD: bus.h,v 1.2 2001/08/20 20:23:52 jason Exp $	*/
2 /*	$NetBSD: bus.h,v 1.28 2001/07/19 15:32:19 thorpej Exp $	*/
3 
4 /*-
5  * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10  * NASA Ames Research Center.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *	This product includes software developed by the NetBSD
23  *	Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /*
42  * Copyright (c) 1997-1999 Eduardo E. Horvath. All rights reserved.
43  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
44  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
45  *
46  * Redistribution and use in source and binary forms, with or without
47  * modification, are permitted provided that the following conditions
48  * are met:
49  * 1. Redistributions of source code must retain the above copyright
50  *    notice, this list of conditions and the following disclaimer.
51  * 2. Redistributions in binary form must reproduce the above copyright
52  *    notice, this list of conditions and the following disclaimer in the
53  *    documentation and/or other materials provided with the distribution.
54  * 3. All advertising materials mentioning features or use of this software
55  *    must display the following acknowledgement:
56  *      This product includes software developed by Christopher G. Demetriou
57  *	for the NetBSD Project.
58  * 4. The name of the author may not be used to endorse or promote products
59  *    derived from this software without specific prior written permission
60  *
61  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
62  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
63  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
64  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
65  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
66  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
67  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
68  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
70  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71  */
72 
73 #ifndef _SPARC_BUS_H_
74 #define _SPARC_BUS_H_
75 
76 #include <machine/types.h>
77 #include <machine/ctlreg.h>
78 
79 /*
80  * Debug hooks
81  */
82 
83 #define	BSDB_ACCESS	0x01
84 #define BSDB_MAP	0x02
85 extern int bus_space_debug;
86 
87 /*
88  * UPA and SBUS spaces are non-cached and big endian
89  * (except for RAM and PROM)
90  *
91  * PCI spaces are non-cached and little endian
92  */
93 
94 enum bus_type {
95 	UPA_BUS_SPACE,
96 	SBUS_BUS_SPACE,
97 	PCI_CONFIG_BUS_SPACE,
98 	PCI_IO_BUS_SPACE,
99 	PCI_MEMORY_BUS_SPACE,
100 	LAST_BUS_SPACE
101 };
102 extern int bus_type_asi[];
103 extern int bus_stream_asi[];
104 /* For backwards compatibility */
105 #define SPARC_BUS_SPACE	UPA_BUS_SPACE
106 
107 #define __BUS_SPACE_HAS_STREAM_METHODS	1
108 
109 /*
110  * Bus address and size types
111  */
112 typedef	u_int64_t	bus_space_handle_t;
113 typedef enum bus_type	bus_type_t;
114 typedef u_int64_t	bus_addr_t;
115 typedef u_int64_t	bus_size_t;
116 
117 /*
118  * Access methods for bus resources and address space.
119  */
120 typedef struct sparc_bus_space_tag	*bus_space_tag_t;
121 
122 struct sparc_bus_space_tag {
123 	void		*cookie;
124 	bus_space_tag_t	parent;
125 	int		type;
126 
127 	int	(*sparc_bus_map) __P((
128 				bus_space_tag_t,
129 				bus_type_t,
130 				bus_addr_t,
131 				bus_size_t,
132 				int,			/*flags*/
133 				vaddr_t,		/*preferred vaddr*/
134 				bus_space_handle_t *));
135 	int	(*sparc_bus_unmap) __P((
136 				bus_space_tag_t,
137 				bus_space_handle_t,
138 				bus_size_t));
139 	int	(*sparc_bus_subregion) __P((
140 				bus_space_tag_t,
141 				bus_space_handle_t,
142 				bus_size_t,		/*offset*/
143 				bus_size_t,		/*size*/
144 				bus_space_handle_t *));
145 
146 	void	(*sparc_bus_barrier) __P((
147 				bus_space_tag_t,
148 				bus_space_handle_t,
149 				bus_size_t,		/*offset*/
150 				bus_size_t,		/*size*/
151 				int));			/*flags*/
152 
153 	int	(*sparc_bus_mmap) __P((
154 				bus_space_tag_t,
155 				bus_type_t,		/**/
156 				bus_addr_t,		/**/
157 				int,			/*flags*/
158 				bus_space_handle_t *));
159 
160 	void	*(*sparc_intr_establish) __P((
161 				bus_space_tag_t,
162 				int,			/*bus-specific intr*/
163 				int,			/*device class level,
164 							  see machine/intr.h*/
165 				int,			/*flags*/
166 				int (*) __P((void *)),	/*handler*/
167 				void *));		/*handler arg*/
168 
169 };
170 
171 #if 0
172 /*
173  * The following macro could be used to generate the bus_space*() functions
174  * but it uses a gcc extension and is ANSI-only.
175 #define PROTO_bus_space_xxx		__P((bus_space_tag_t t, ...))
176 #define RETURNTYPE_bus_space_xxx	void *
177 #define BUSFUN(name, returntype, t, args...)			\
178 	__inline__ RETURNTYPE_##name				\
179 	bus_##name PROTO_##name					\
180 	{							\
181 		while (t->sparc_##name == NULL)			\
182 			t = t->parent;				\
183 		return (*(t)->sparc_##name)(t, args);		\
184 	}
185  */
186 #endif
187 
188 /*
189  * Bus space function prototypes.
190  */
191 static int	bus_space_map __P((
192 				bus_space_tag_t,
193 				bus_addr_t,
194 				bus_size_t,
195 				int,			/*flags*/
196 				bus_space_handle_t *));
197 static int	bus_space_map2 __P((
198 				bus_space_tag_t,
199 				bus_type_t,
200 				bus_addr_t,
201 				bus_size_t,
202 				int,			/*flags*/
203 				vaddr_t,		/*preferred vaddr*/
204 				bus_space_handle_t *));
205 static int	bus_space_unmap __P((
206 				bus_space_tag_t,
207 				bus_space_handle_t,
208 				bus_size_t));
209 static int	bus_space_subregion __P((
210 				bus_space_tag_t,
211 				bus_space_handle_t,
212 				bus_size_t,
213 				bus_size_t,
214 				bus_space_handle_t *));
215 static void	bus_space_barrier __P((
216 				bus_space_tag_t,
217 				bus_space_handle_t,
218 				bus_size_t,
219 				bus_size_t,
220 				int));
221 static int	bus_space_mmap __P((
222 				bus_space_tag_t,
223 				bus_type_t,		/**/
224 				bus_addr_t,		/**/
225 				int,			/*flags*/
226 				bus_space_handle_t *));
227 static void	*bus_intr_establish __P((
228 				bus_space_tag_t,
229 				int,			/*bus-specific intr*/
230 				int,			/*device class level,
231 							  see machine/intr.h*/
232 				int,			/*flags*/
233 				int (*) __P((void *)),	/*handler*/
234 				void *));		/*handler arg*/
235 
236 
237 /* This macro finds the first "upstream" implementation of method `f' */
238 #define _BS_CALL(t,f)			\
239 	while (t->f == NULL)		\
240 		t = t->parent;		\
241 	return (*(t)->f)
242 
243 __inline__ int
244 bus_space_map(t, a, s, f, hp)
245 	bus_space_tag_t	t;
246 	bus_addr_t	a;
247 	bus_size_t	s;
248 	int		f;
249 	bus_space_handle_t *hp;
250 {
251 	_BS_CALL(t, sparc_bus_map)((t), 0, (a), (s), (f), 0, (hp));
252 }
253 
254 __inline__ int
255 bus_space_map2(t, bt, a, s, f, v, hp)
256 	bus_space_tag_t	t;
257 	bus_type_t	bt;
258 	bus_addr_t	a;
259 	bus_size_t	s;
260 	int		f;
261 	vaddr_t	v;
262 	bus_space_handle_t *hp;
263 {
264 	_BS_CALL(t, sparc_bus_map)(t, bt, a, s, f, v, hp);
265 }
266 
267 __inline__ int
268 bus_space_unmap(t, h, s)
269 	bus_space_tag_t t;
270 	bus_space_handle_t h;
271 	bus_size_t	s;
272 {
273 	_BS_CALL(t, sparc_bus_unmap)(t, h, s);
274 }
275 
276 __inline__ int
277 bus_space_subregion(t, h, o, s, hp)
278 	bus_space_tag_t	t;
279 	bus_space_handle_t h;
280 	bus_size_t	o;
281 	bus_size_t	s;
282 	bus_space_handle_t *hp;
283 {
284 	_BS_CALL(t, sparc_bus_subregion)(t, h, o, s, hp);
285 }
286 
287 __inline__ int
288 bus_space_mmap(t, bt, a, f, hp)
289 	bus_space_tag_t	t;
290 	bus_type_t	bt;
291 	bus_addr_t	a;
292 	int		f;
293 	bus_space_handle_t *hp;
294 {
295 	_BS_CALL(t, sparc_bus_mmap)(t, bt, a, f, hp);
296 }
297 
298 __inline__ void *
299 bus_intr_establish(t, p, l, f, h, a)
300 	bus_space_tag_t t;
301 	int	p;
302 	int	l;
303 	int	f;
304 	int	(*h)__P((void *));
305 	void	*a;
306 {
307 	_BS_CALL(t, sparc_intr_establish)(t, p, l, f, h, a);
308 }
309 
310 __inline__ void
311 bus_space_barrier(t, h, o, s, f)
312 	bus_space_tag_t t;
313 	bus_space_handle_t h;
314 	bus_size_t o;
315 	bus_size_t s;
316 	int f;
317 {
318 	_BS_CALL(t, sparc_bus_barrier)(t, h, o, s, f);
319 }
320 
321 
322 #if 0
323 int	bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
324 	    bus_addr_t rend, bus_size_t size, bus_size_t align,
325 	    bus_size_t boundary, int flags, bus_addr_t *addrp,
326 	    bus_space_handle_t *bshp));
327 void	bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
328 	    bus_size_t size));
329 #endif
330 
331 /* flags for bus space map functions */
332 #define BUS_SPACE_MAP_CACHEABLE		0x0001
333 #define BUS_SPACE_MAP_LINEAR		0x0002
334 #define BUS_SPACE_MAP_READONLY		0x0004
335 #define BUS_SPACE_MAP_PREFETCHABLE	0x0008
336 #define BUS_SPACE_MAP_BUS1	0x0100	/* placeholders for bus functions... */
337 #define BUS_SPACE_MAP_BUS2	0x0200
338 #define BUS_SPACE_MAP_BUS3	0x0400
339 #define BUS_SPACE_MAP_BUS4	0x0800
340 
341 
342 /* flags for intr_establish() */
343 #define BUS_INTR_ESTABLISH_FASTTRAP	1
344 #define BUS_INTR_ESTABLISH_SOFTINTR	2
345 
346 /* flags for bus_space_barrier() */
347 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
348 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
349 
350 /*
351  * Device space probe assistant.
352  * The optional callback function's arguments are:
353  *	the temporary virtual address
354  *	the passed `arg' argument
355  */
356 int bus_space_probe __P((
357 		bus_space_tag_t,
358 		bus_type_t,
359 		bus_addr_t,
360 		bus_size_t,			/* probe size */
361 		size_t,				/* offset */
362 		int,				/* flags */
363 		int (*) __P((void *, void *)),	/* callback function */
364 		void *));			/* callback arg */
365 
366 
367 /*
368  *	u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
369  *	    bus_space_handle_t bsh, bus_size_t offset));
370  *
371  * Read a 1, 2, 4, or 8 byte quantity from bus space
372  * described by tag/handle/offset.
373  */
374 #ifndef BUS_SPACE_DEBUG
375 #define	bus_space_read_1(t, h, o)					\
376 	    lduba((h) + (o), bus_type_asi[(t)->type])
377 
378 #define	bus_space_read_2(t, h, o)					\
379 	    lduha((h) + (o), bus_type_asi[(t)->type])
380 
381 #define	bus_space_read_4(t, h, o)					\
382 	    lda((h) + (o), bus_type_asi[(t)->type])
383 
384 #define	bus_space_read_8(t, h, o)					\
385 	    ldxa((h) + (o), bus_type_asi[(t)->type])
386 #else
387 #define	bus_space_read_1(t, h, o) ({					\
388 	unsigned char __bv =				      		\
389 	    lduba((h) + (o), bus_type_asi[(t)->type]);			\
390 	if (bus_space_debug & BSDB_ACCESS)				\
391 	printf("bsr1(%llx + %llx, %x) -> %x\n", (u_int64_t)(h),		\
392 		(u_int64_t)(o),						\
393 		bus_type_asi[(t)->type], (unsigned int) __bv);		\
394 	__bv; })
395 
396 #define	bus_space_read_2(t, h, o) ({					\
397 	unsigned short __bv =				      		\
398 	    lduha((h) + (o), bus_type_asi[(t)->type]);			\
399 	if (bus_space_debug & BSDB_ACCESS)				\
400 	printf("bsr2(%llx + %llx, %x) -> %x\n", (u_int64_t)(h),		\
401 		(u_int64_t)(o),						\
402 		bus_type_asi[(t)->type], (unsigned int)__bv);		\
403 	__bv; })
404 
405 #define	bus_space_read_4(t, h, o) ({					\
406 	unsigned int __bv =				      		\
407 	    lda((h) + (o), bus_type_asi[(t)->type]);			\
408 	if (bus_space_debug & BSDB_ACCESS)				\
409 	printf("bsr4(%llx + %llx, %x) -> %x\n", (u_int64_t)(h),		\
410 		(u_int64_t)(o),						\
411 		bus_type_asi[(t)->type], __bv);				\
412 	__bv; })
413 
414 #define	bus_space_read_8(t, h, o) ({					\
415 	u_int64_t __bv =				      		\
416 	    ldxa((h) + (o), bus_type_asi[(t)->type]);			\
417 	if (bus_space_debug & BSDB_ACCESS)				\
418 	printf("bsr8(%llx + %llx, %x) -> %llx\n", (u_int64_t)(h),	\
419 		(u_int64_t)(o),						\
420 		bus_type_asi[(t)->type], __bv);				\
421 	__bv; })
422 #endif
423 /*
424  *	void bus_space_read_multi_N __P((bus_space_tag_t tag,
425  *	    bus_space_handle_t bsh, bus_size_t offset,
426  *	    u_intN_t *addr, size_t count));
427  *
428  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
429  * described by tag/handle/offset and copy into buffer provided.
430  */
431 
432 #define	bus_space_read_multi_1(t, h, o, a, c) do {			\
433 	int i = c;							\
434 	u_int8_t *p = (u_int8_t *)a;					\
435 	while (i-- > 0)							\
436 		*p++ = bus_space_read_1(t, h, o);			\
437 } while (0)
438 
439 #define	bus_space_read_multi_2(t, h, o, a, c) do {			\
440 	int i = c;							\
441 	u_int16_t *p = (u_int16_t *)a;					\
442 	while (i-- > 0)							\
443 		*p++ = bus_space_read_2(t, h, o);			\
444 } while (0)
445 
446 #define	bus_space_read_multi_4(t, h, o, a, c) do {			\
447 	int i = c;							\
448 	u_int32_t *p = (u_int32_t *)a;					\
449 	while (i-- > 0)							\
450 		*p++ = bus_space_read_4(t, h, o);			\
451 } while (0)
452 
453 #define	bus_space_read_multi_8(t, h, o, a, c) do {			\
454 	int i = c;							\
455 	u_int64_t *p = (u_int64_t *)a;					\
456 	while (i-- > 0)							\
457 		*p++ = bus_space_read_8(t, h, o);			\
458 } while (0)
459 
460 /*
461  *	void bus_space_write_N __P((bus_space_tag_t tag,
462  *	    bus_space_handle_t bsh, bus_size_t offset,
463  *	    u_intN_t value));
464  *
465  * Write the 1, 2, 4, or 8 byte value `value' to bus space
466  * described by tag/handle/offset.
467  */
468 #ifndef BUS_SPACE_DEBUG
469 #define	bus_space_write_1(t, h, o, v)					\
470 	((void)(stba((h) + (o), bus_type_asi[(t)->type], (v))))
471 
472 #define	bus_space_write_2(t, h, o, v)					\
473 	((void)(stha((h) + (o), bus_type_asi[(t)->type], (v))))
474 
475 #define	bus_space_write_4(t, h, o, v)					\
476 	((void)(sta((h) + (o), bus_type_asi[(t)->type], (v))))
477 
478 #define	bus_space_write_8(t, h, o, v)					\
479 	((void)(stxa((h) + (o), bus_type_asi[(t)->type], (v))))
480 #else
481 #define	bus_space_write_1(t, h, o, v) ({				\
482 	if (bus_space_debug & BSDB_ACCESS)				\
483 	printf("bsw1(%llx + %llx, %x) <- %x\n", (u_int64_t)(h),		\
484 		(u_int64_t)(o),						\
485 		bus_type_asi[(t)->type], (unsigned int) v);		\
486 	((void)(stba((h) + (o), bus_type_asi[(t)->type], (v))));  })
487 
488 #define	bus_space_write_2(t, h, o, v) ({				\
489 	if (bus_space_debug & BSDB_ACCESS)				\
490 	printf("bsw2(%llx + %llx, %x) <- %x\n", (u_int64_t)(h),		\
491 		(u_int64_t)(o),						\
492 		bus_type_asi[(t)->type], (unsigned int) v);		\
493 	((void)(stha((h) + (o), bus_type_asi[(t)->type], (v)))); })
494 
495 #define	bus_space_write_4(t, h, o, v) ({				\
496 	if (bus_space_debug & BSDB_ACCESS)				\
497 	printf("bsw4(%llx + %llx, %x) <- %x\n", (u_int64_t)(h),		\
498 		(u_int64_t)(o),						\
499 		bus_type_asi[(t)->type], (unsigned int) v);		\
500 	((void)(sta((h) + (o), bus_type_asi[(t)->type], (v)))); })
501 
502 #define	bus_space_write_8(t, h, o, v) ({				\
503 	if (bus_space_debug & BSDB_ACCESS)				\
504 	printf("bsw8(%llx + %llx, %x) <- %llx\n", (u_int64_t)(h),	\
505 		(u_int64_t)(o),						\
506 		bus_type_asi[(t)->type], (u_int64_t) v);		\
507 	((void)(stxa((h) + (o), bus_type_asi[(t)->type], (v)))); })
508 #endif
509 /*
510  *	void bus_space_write_multi_N __P((bus_space_tag_t tag,
511  *	    bus_space_handle_t bsh, bus_size_t offset,
512  *	    const u_intN_t *addr, size_t count));
513  *
514  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
515  * provided to bus space described by tag/handle/offset.
516  */
517 
518 #define	bus_space_write_multi_1(t, h, o, a, c) do {			\
519 	int i = c;							\
520 	u_int8_t *p = (u_int8_t *)a;					\
521 	while (i-- > 0)							\
522 		bus_space_write_1(t, h, o, *p++);			\
523 } while (0)
524 
525 #define bus_space_write_multi_2(t, h, o, a, c) do {			\
526 	int i = c;							\
527 	u_int16_t *p = (u_int16_t *)a;					\
528 	while (i-- > 0)							\
529 		bus_space_write_2(t, h, o, *p++);			\
530 } while (0)
531 
532 #define bus_space_write_multi_4(t, h, o, a, c) do {			\
533 	int i = c;							\
534 	u_int32_t *p = (u_int32_t *)a;					\
535 	while (i-- > 0)							\
536 		bus_space_write_4(t, h, o, *p++);			\
537 } while (0)
538 
539 #define bus_space_write_multi_8(t, h, o, a, c) do {			\
540 	int i = c;							\
541 	u_int64_t *p = (u_int64_t *)a;					\
542 	while (i-- > 0)							\
543 		bus_space_write_8(t, h, o, *p++);			\
544 } while (0)
545 
546 /*
547  *	void bus_space_set_multi_N __P((bus_space_tag_t tag,
548  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
549  *	    size_t count));
550  *
551  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
552  * by tag/handle/offset `count' times.
553  */
554 
555 #define bus_space_set_multi_1(t, h, o, v, c) do {			\
556 	int i = c;							\
557 	while (i-- > 0)							\
558 		bus_space_write_1(t, h, o, v);				\
559 } while (0)
560 
561 #define bus_space_set_multi_2(t, h, o, v, c) do {			\
562 	int i = c;							\
563 	while (i-- > 0)							\
564 		bus_space_write_2(t, h, o, v);				\
565 } while (0)
566 
567 #define bus_space_set_multi_4(t, h, o, v, c) do {			\
568 	int i = c;							\
569 	while (i-- > 0)							\
570 		bus_space_write_4(t, h, o, v);				\
571 } while (0)
572 
573 #define bus_space_set_multi_8(t, h, o, v, c) do {			\
574 	int i = c;							\
575 	while (i-- > 0)							\
576 		bus_space_write_8(t, h, o, v);				\
577 } while (0)
578 
579 /*
580  *	void bus_space_read_region_N __P((bus_space_tag_t tag,
581  *	    bus_space_handle_t bsh, bus_size_t off,
582  *	    u_intN_t *addr, bus_size_t count));
583  *
584  */
585 static void bus_space_read_region_1 __P((bus_space_tag_t,
586 	bus_space_handle_t,
587 	bus_size_t,
588 	u_int8_t *,
589 	bus_size_t));
590 static void bus_space_read_region_2 __P((bus_space_tag_t,
591 	bus_space_handle_t,
592 	bus_size_t,
593 	u_int16_t *,
594 	bus_size_t));
595 static void bus_space_read_region_4 __P((bus_space_tag_t,
596 	bus_space_handle_t,
597 	bus_size_t,
598 	u_int32_t *,
599 	bus_size_t));
600 static void bus_space_read_region_8 __P((bus_space_tag_t,
601 	bus_space_handle_t,
602 	bus_size_t,
603 	u_int64_t *,
604 	bus_size_t));
605 
606 static __inline__ void
607 bus_space_read_region_1(t, h, o, a, c)
608 	bus_space_tag_t		t;
609 	bus_space_handle_t	h;
610 	bus_size_t		o, c;
611 	u_int8_t		*a;
612 {
613 	for (; c; a++, c--, o++)
614 		*a = bus_space_read_1(t, h, o);
615 }
616 static __inline__ void
617 bus_space_read_region_2(t, h, o, a, c)
618 	bus_space_tag_t		t;
619 	bus_space_handle_t	h;
620 	bus_size_t		o, c;
621 	u_int16_t		*a;
622 {
623 	for (; c; a++, c--, o+=2)
624 		*a = bus_space_read_2(t, h, o);
625  }
626 static __inline__ void
627 bus_space_read_region_4(t, h, o, a, c)
628 	bus_space_tag_t		t;
629 	bus_space_handle_t	h;
630 	bus_size_t		o, c;
631 	u_int32_t		*a;
632 {
633 	for (; c; a++, c--, o+=4)
634 		*a = bus_space_read_4(t, h, o);
635 }
636 static __inline__ void
637 bus_space_read_region_8(t, h, o, a, c)
638 	bus_space_tag_t		t;
639 	bus_space_handle_t	h;
640 	bus_size_t		o, c;
641 	u_int64_t		*a;
642 {
643 	for (; c; a++, c--, o+=8)
644 		*a = bus_space_read_8(t, h, o);
645 }
646 
647 /*
648  *	void bus_space_write_region_N __P((bus_space_tag_t tag,
649  *	    bus_space_handle_t bsh, bus_size_t off,
650  *	    u_intN_t *addr, bus_size_t count));
651  *
652  */
653 static void bus_space_write_region_1 __P((bus_space_tag_t,
654 	bus_space_handle_t,
655 	bus_size_t,
656 	const u_int8_t *,
657 	bus_size_t));
658 static void bus_space_write_region_2 __P((bus_space_tag_t,
659 	bus_space_handle_t,
660 	bus_size_t,
661 	const u_int16_t *,
662 	bus_size_t));
663 static void bus_space_write_region_4 __P((bus_space_tag_t,
664 	bus_space_handle_t,
665 	bus_size_t,
666 	const u_int32_t *,
667 	bus_size_t));
668 static void bus_space_write_region_8 __P((bus_space_tag_t,
669 	bus_space_handle_t,
670 	bus_size_t,
671 	const u_int64_t *,
672 	bus_size_t));
673 static __inline__ void
674 bus_space_write_region_1(t, h, o, a, c)
675 	bus_space_tag_t		t;
676 	bus_space_handle_t	h;
677 	bus_size_t		o, c;
678 	const u_int8_t		*a;
679 {
680 	for (; c; a++, c--, o++)
681 		bus_space_write_1(t, h, o, *a);
682 }
683 
684 static __inline__ void
685 bus_space_write_region_2(t, h, o, a, c)
686 	bus_space_tag_t		t;
687 	bus_space_handle_t	h;
688 	bus_size_t		o, c;
689 	const u_int16_t		*a;
690 {
691 	for (; c; a++, c--, o+=2)
692 		bus_space_write_2(t, h, o, *a);
693 }
694 
695 static __inline__ void
696 bus_space_write_region_4(t, h, o, a, c)
697 	bus_space_tag_t		t;
698 	bus_space_handle_t	h;
699 	bus_size_t		o, c;
700 	const u_int32_t		*a;
701 {
702 	for (; c; a++, c--, o+=4)
703 		bus_space_write_4(t, h, o, *a);
704 }
705 
706 static __inline__ void
707 bus_space_write_region_8(t, h, o, a, c)
708 	bus_space_tag_t		t;
709 	bus_space_handle_t	h;
710 	bus_size_t		o, c;
711 	const u_int64_t		*a;
712 {
713 	for (; c; a++, c--, o+=8)
714 		bus_space_write_8(t, h, o, *a);
715 }
716 
717 
718 /*
719  *	void bus_space_set_region_N __P((bus_space_tag_t tag,
720  *	    bus_space_handle_t bsh, bus_size_t off,
721  *	    u_intN_t *addr, bus_size_t count));
722  *
723  */
724 static void bus_space_set_region_1 __P((bus_space_tag_t,
725 	bus_space_handle_t,
726 	bus_size_t,
727 	const u_int8_t,
728 	bus_size_t));
729 static void bus_space_set_region_2 __P((bus_space_tag_t,
730 	bus_space_handle_t,
731 	bus_size_t,
732 	const u_int16_t,
733 	bus_size_t));
734 static void bus_space_set_region_4 __P((bus_space_tag_t,
735 	bus_space_handle_t,
736 	bus_size_t,
737 	const u_int32_t,
738 	bus_size_t));
739 static void bus_space_set_region_8 __P((bus_space_tag_t,
740 	bus_space_handle_t,
741 	bus_size_t,
742 	const u_int64_t,
743 	bus_size_t));
744 
745 static __inline__ void
746 bus_space_set_region_1(t, h, o, v, c)
747 	bus_space_tag_t		t;
748 	bus_space_handle_t	h;
749 	bus_size_t		o, c;
750 	const u_int8_t		v;
751 {
752 	for (; c; c--, o++)
753 		bus_space_write_1(t, h, o, v);
754 }
755 
756 static __inline__ void
757 bus_space_set_region_2(t, h, o, v, c)
758 	bus_space_tag_t		t;
759 	bus_space_handle_t	h;
760 	bus_size_t		o, c;
761 	const u_int16_t		v;
762 {
763 	for (; c; c--, o+=2)
764 		bus_space_write_2(t, h, o, v);
765 }
766 
767 static __inline__ void
768 bus_space_set_region_4(t, h, o, v, c)
769 	bus_space_tag_t		t;
770 	bus_space_handle_t	h;
771 	bus_size_t		o, c;
772 	const u_int32_t		v;
773 {
774 	for (; c; c--, o+=4)
775 		bus_space_write_4(t, h, o, v);
776 }
777 
778 static __inline__ void
779 bus_space_set_region_8(t, h, o, v, c)
780 	bus_space_tag_t		t;
781 	bus_space_handle_t	h;
782 	bus_size_t		o, c;
783 	const u_int64_t		v;
784 {
785 	for (; c; c--, o+=8)
786 		bus_space_write_8(t, h, o, v);
787 }
788 
789 
790 /*
791  *	void bus_space_copy_region_N __P((bus_space_tag_t tag,
792  *	    bus_space_handle_t bsh1, bus_size_t off1,
793  *	    bus_space_handle_t bsh2, bus_size_t off2,
794  *	    bus_size_t count));
795  *
796  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
797  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
798  */
799 static void bus_space_copy_region_1 __P((bus_space_tag_t,
800 	bus_space_handle_t,
801 	bus_size_t,
802 	bus_space_handle_t,
803 	bus_size_t,
804 	bus_size_t));
805 static void bus_space_copy_region_2 __P((bus_space_tag_t,
806 	bus_space_handle_t,
807 	bus_size_t,
808 	bus_space_handle_t,
809 	bus_size_t,
810 	bus_size_t));
811 static void bus_space_copy_region_4 __P((bus_space_tag_t,
812 	bus_space_handle_t,
813 	bus_size_t,
814 	bus_space_handle_t,
815 	bus_size_t,
816 	bus_size_t));
817 static void bus_space_copy_region_8 __P((bus_space_tag_t,
818 	bus_space_handle_t,
819 	bus_size_t,
820 	bus_space_handle_t,
821 	bus_size_t,
822 	bus_size_t));
823 
824 
825 static __inline__ void
826 bus_space_copy_region_1(t, h1, o1, h2, o2, c)
827 	bus_space_tag_t		t;
828 	bus_space_handle_t	h1, h2;
829 	bus_size_t		o1, o2;
830 	bus_size_t		c;
831 {
832 	for (; c; c--, o1++, o2++)
833 	    bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2));
834 }
835 
836 static __inline__ void
837 bus_space_copy_region_2(t, h1, o1, h2, o2, c)
838 	bus_space_tag_t		t;
839 	bus_space_handle_t	h1, h2;
840 	bus_size_t		o1, o2;
841 	bus_size_t		c;
842 {
843 	for (; c; c--, o1+=2, o2+=2)
844 	    bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2));
845 }
846 
847 static __inline__ void
848 bus_space_copy_region_4(t, h1, o1, h2, o2, c)
849 	bus_space_tag_t		t;
850 	bus_space_handle_t	h1, h2;
851 	bus_size_t		o1, o2;
852 	bus_size_t		c;
853 {
854 	for (; c; c--, o1+=4, o2+=4)
855 	    bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2));
856 }
857 
858 static __inline__ void
859 bus_space_copy_region_8(t, h1, o1, h2, o2, c)
860 	bus_space_tag_t		t;
861 	bus_space_handle_t	h1, h2;
862 	bus_size_t		o1, o2;
863 	bus_size_t		c;
864 {
865 	for (; c; c--, o1+=8, o2+=8)
866 	    bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2));
867 }
868 
869 /*
870  *	u_intN_t bus_space_read_stream_N __P((bus_space_tag_t tag,
871  *	    bus_space_handle_t bsh, bus_size_t offset));
872  *
873  * Read a 1, 2, 4, or 8 byte quantity from bus space
874  * described by tag/handle/offset.
875  */
876 #ifndef BUS_SPACE_DEBUG
877 #define	bus_space_read_stream_1(t, h, o)				\
878 	    lduba((h) + (o), bus_stream_asi[(t)->type])
879 
880 #define	bus_space_read_stream_2(t, h, o)				\
881 	    lduha((h) + (o), bus_stream_asi[(t)->type])
882 
883 #define	bus_space_read_stream_4(t, h, o)				\
884 	    lda((h) + (o), bus_stream_asi[(t)->type])
885 
886 #define	bus_space_read_stream_8(t, h, o)				\
887 	    ldxa((h) + (o), bus_stream_asi[(t)->type])
888 #else
889 #define	bus_space_read_stream_1(t, h, o) ({				\
890 	unsigned char __bv =				      		\
891 	    lduba((h) + (o), bus_stream_asi[(t)->type]);			\
892 	if (bus_space_debug & BSDB_ACCESS)				\
893 	printf("bsr1(%llx + %llx, %x) -> %x\n", (u_int64_t)(h),		\
894 		(u_int64_t)(o),						\
895 		bus_stream_asi[(t)->type], (unsigned int) __bv);		\
896 	__bv; })
897 
898 #define	bus_space_read_stream_2(t, h, o) ({				\
899 	unsigned short __bv =				      		\
900 	    lduha((h) + (o), bus_stream_asi[(t)->type]);			\
901 	if (bus_space_debug & BSDB_ACCESS)				\
902 	printf("bsr2(%llx + %llx, %x) -> %x\n", (u_int64_t)(h),		\
903 		(u_int64_t)(o),						\
904 		bus_stream_asi[(t)->type], (unsigned int)__bv);		\
905 	__bv; })
906 
907 #define	bus_space_read_stream_4(t, h, o) ({					\
908 	unsigned int __bv =				      		\
909 	    lda((h) + (o), bus_stream_asi[(t)->type]);			\
910 	if (bus_space_debug & BSDB_ACCESS)				\
911 	printf("bsr4(%llx + %llx, %x) -> %x\n", (u_int64_t)(h),		\
912 		(u_int64_t)(o),						\
913 		bus_stream_asi[(t)->type], __bv);				\
914 	__bv; })
915 
916 #define	bus_space_read_stream_8(t, h, o) ({					\
917 	u_int64_t __bv =				      		\
918 	    ldxa((h) + (o), bus_stream_asi[(t)->type]);			\
919 	if (bus_space_debug & BSDB_ACCESS)				\
920 	printf("bsr8(%llx + %llx, %x) -> %llx\n", (u_int64_t)(h),	\
921 		(u_int64_t)(o),						\
922 		bus_stream_asi[(t)->type], __bv);				\
923 	__bv; })
924 #endif
925 /*
926  *	void bus_space_read_multi_stream_N __P((bus_space_tag_t tag,
927  *	    bus_space_handle_t bsh, bus_size_t offset,
928  *	    u_intN_t *addr, size_t count));
929  *
930  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
931  * described by tag/handle/offset and copy into buffer provided.
932  */
933 
934 #define	bus_space_read_multi_stream_1(t, h, o, a, c) do {			\
935 	int i = c;							\
936 	u_int8_t *p = (u_int8_t *)a;					\
937 	while (i-- > 0)							\
938 		*p++ = bus_space_read_stream_1(t, h, o);			\
939 } while (0)
940 
941 #define	bus_space_read_multi_stream_2(t, h, o, a, c) do {			\
942 	int i = c;							\
943 	u_int16_t *p = (u_int16_t *)a;					\
944 	while (i-- > 0)							\
945 		*p++ = bus_space_read_stream_2(t, h, o);			\
946 } while (0)
947 
948 #define	bus_space_read_multi_stream_4(t, h, o, a, c) do {			\
949 	int i = c;							\
950 	u_int32_t *p = (u_int32_t *)a;					\
951 	while (i-- > 0)							\
952 		*p++ = bus_space_read_stream_4(t, h, o);			\
953 } while (0)
954 
955 #define	bus_space_read_multi_stream_8(t, h, o, a, c) do {			\
956 	int i = c;							\
957 	u_int64_t *p = (u_int64_t *)a;					\
958 	while (i-- > 0)							\
959 		*p++ = bus_space_read_stream_8(t, h, o);			\
960 } while (0)
961 
962 /*
963  *	void bus_space_write_stream_N __P((bus_space_tag_t tag,
964  *	    bus_space_handle_t bsh, bus_size_t offset,
965  *	    u_intN_t value));
966  *
967  * Write the 1, 2, 4, or 8 byte value `value' to bus space
968  * described by tag/handle/offset.
969  */
970 #ifndef BUS_SPACE_DEBUG
971 #define	bus_space_write_stream_1(t, h, o, v)					\
972 	((void)(stba((h) + (o), bus_stream_asi[(t)->type], (v))))
973 
974 #define	bus_space_write_stream_2(t, h, o, v)					\
975 	((void)(stha((h) + (o), bus_stream_asi[(t)->type], (v))))
976 
977 #define	bus_space_write_stream_4(t, h, o, v)					\
978 	((void)(sta((h) + (o), bus_stream_asi[(t)->type], (v))))
979 
980 #define	bus_space_write_stream_8(t, h, o, v)					\
981 	((void)(stxa((h) + (o), bus_stream_asi[(t)->type], (v))))
982 #else
983 #define	bus_space_write_stream_1(t, h, o, v) ({				\
984 	if (bus_space_debug & BSDB_ACCESS)				\
985 	printf("bsw1(%llx + %llx, %x) <- %x\n", (u_int64_t)(h),		\
986 		(u_int64_t)(o),						\
987 		bus_stream_asi[(t)->type], (unsigned int) v);		\
988 	((void)(stba((h) + (o), bus_stream_asi[(t)->type], (v))));  })
989 
990 #define	bus_space_write_stream_2(t, h, o, v) ({				\
991 	if (bus_space_debug & BSDB_ACCESS)				\
992 	printf("bsw2(%llx + %llx, %x) <- %x\n", (u_int64_t)(h),		\
993 		(u_int64_t)(o),						\
994 		bus_stream_asi[(t)->type], (unsigned int) v);		\
995 	((void)(stha((h) + (o), bus_stream_asi[(t)->type], (v)))); })
996 
997 #define	bus_space_write_stream_4(t, h, o, v) ({				\
998 	if (bus_space_debug & BSDB_ACCESS)				\
999 	printf("bsw4(%llx + %llx, %x) <- %x\n", (u_int64_t)(h),		\
1000 		(u_int64_t)(o),						\
1001 		bus_stream_asi[(t)->type], (unsigned int) v);		\
1002 	((void)(sta((h) + (o), bus_stream_asi[(t)->type], (v)))); })
1003 
1004 #define	bus_space_write_stream_8(t, h, o, v) ({				\
1005 	if (bus_space_debug & BSDB_ACCESS)				\
1006 	printf("bsw8(%llx + %llx, %x) <- %llx\n", (u_int64_t)(h),	\
1007 		(u_int64_t)(o),						\
1008 		bus_stream_asi[(t)->type], (u_int64_t) v);		\
1009 	((void)(stxa((h) + (o), bus_stream_asi[(t)->type], (v)))); })
1010 #endif
1011 /*
1012  *	void bus_space_write_multi_stream_N __P((bus_space_tag_t tag,
1013  *	    bus_space_handle_t bsh, bus_size_t offset,
1014  *	    const u_intN_t *addr, size_t count));
1015  *
1016  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
1017  * provided to bus space described by tag/handle/offset.
1018  */
1019 
1020 #define	bus_space_write_multi_stream_1(t, h, o, a, c) do {			\
1021 	int i = c;							\
1022 	u_int8_t *p = (u_int8_t *)a;					\
1023 	while (i-- > 0)							\
1024 		bus_space_write_stream_1(t, h, o, *p++);			\
1025 } while (0)
1026 
1027 #define bus_space_write_multi_stream_2(t, h, o, a, c) do {			\
1028 	int i = c;							\
1029 	u_int16_t *p = (u_int16_t *)a;					\
1030 	while (i-- > 0)							\
1031 		bus_space_write_stream_2(t, h, o, *p++);			\
1032 } while (0)
1033 
1034 #define bus_space_write_multi_stream_4(t, h, o, a, c) do {			\
1035 	int i = c;							\
1036 	u_int32_t *p = (u_int32_t *)a;					\
1037 	while (i-- > 0)							\
1038 		bus_space_write_stream_4(t, h, o, *p++);			\
1039 } while (0)
1040 
1041 #define bus_space_write_multi_stream_8(t, h, o, a, c) do {			\
1042 	int i = c;							\
1043 	u_int64_t *p = (u_int64_t *)a;					\
1044 	while (i-- > 0)							\
1045 		bus_space_write_stream_8(t, h, o, *p++);			\
1046 } while (0)
1047 
1048 /*
1049  *	void bus_space_set_multi_stream_N __P((bus_space_tag_t tag,
1050  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
1051  *	    size_t count));
1052  *
1053  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
1054  * by tag/handle/offset `count' times.
1055  */
1056 
1057 #define bus_space_set_multi_stream_1(t, h, o, v, c) do {			\
1058 	int i = c;							\
1059 	while (i-- > 0)							\
1060 		bus_space_write_stream_1(t, h, o, v);				\
1061 } while (0)
1062 
1063 #define bus_space_set_multi_stream_2(t, h, o, v, c) do {			\
1064 	int i = c;							\
1065 	while (i-- > 0)							\
1066 		bus_space_write_stream_2(t, h, o, v);				\
1067 } while (0)
1068 
1069 #define bus_space_set_multi_stream_4(t, h, o, v, c) do {			\
1070 	int i = c;							\
1071 	while (i-- > 0)							\
1072 		bus_space_write_stream_4(t, h, o, v);				\
1073 } while (0)
1074 
1075 #define bus_space_set_multi_stream_8(t, h, o, v, c) do {			\
1076 	int i = c;							\
1077 	while (i-- > 0)							\
1078 		bus_space_write_stream_8(t, h, o, v);				\
1079 } while (0)
1080 
1081 /*
1082  *	void bus_space_read_region_stream_N __P((bus_space_tag_t tag,
1083  *	    bus_space_handle_t bsh, bus_size_t off,
1084  *	    u_intN_t *addr, bus_size_t count));
1085  *
1086  */
1087 static void bus_space_read_region_stream_1 __P((bus_space_tag_t,
1088 	bus_space_handle_t,
1089 	bus_size_t,
1090 	u_int8_t *,
1091 	bus_size_t));
1092 static void bus_space_read_region_stream_2 __P((bus_space_tag_t,
1093 	bus_space_handle_t,
1094 	bus_size_t,
1095 	u_int16_t *,
1096 	bus_size_t));
1097 static void bus_space_read_region_stream_4 __P((bus_space_tag_t,
1098 	bus_space_handle_t,
1099 	bus_size_t,
1100 	u_int32_t *,
1101 	bus_size_t));
1102 static void bus_space_read_region_stream_8 __P((bus_space_tag_t,
1103 	bus_space_handle_t,
1104 	bus_size_t,
1105 	u_int64_t *,
1106 	bus_size_t));
1107 
1108 static __inline__ void
1109 bus_space_read_region_stream_1(t, h, o, a, c)
1110 	bus_space_tag_t		t;
1111 	bus_space_handle_t	h;
1112 	bus_size_t		o, c;
1113 	u_int8_t		*a;
1114 {
1115 	for (; c; a++, c--, o++)
1116 		*a = bus_space_read_stream_1(t, h, o);
1117 }
1118 static __inline__ void
1119 bus_space_read_region_stream_2(t, h, o, a, c)
1120 	bus_space_tag_t		t;
1121 	bus_space_handle_t	h;
1122 	bus_size_t		o, c;
1123 	u_int16_t		*a;
1124 {
1125 	for (; c; a++, c--, o+=2)
1126 		*a = bus_space_read_stream_2(t, h, o);
1127  }
1128 static __inline__ void
1129 bus_space_read_region_stream_4(t, h, o, a, c)
1130 	bus_space_tag_t		t;
1131 	bus_space_handle_t	h;
1132 	bus_size_t		o, c;
1133 	u_int32_t		*a;
1134 {
1135 	for (; c; a++, c--, o+=4)
1136 		*a = bus_space_read_stream_4(t, h, o);
1137 }
1138 static __inline__ void
1139 bus_space_read_region_stream_8(t, h, o, a, c)
1140 	bus_space_tag_t		t;
1141 	bus_space_handle_t	h;
1142 	bus_size_t		o, c;
1143 	u_int64_t		*a;
1144 {
1145 	for (; c; a++, c--, o+=8)
1146 		*a = bus_space_read_stream_8(t, h, o);
1147 }
1148 
1149 /*
1150  *	void bus_space_write_region_stream_N __P((bus_space_tag_t tag,
1151  *	    bus_space_handle_t bsh, bus_size_t off,
1152  *	    u_intN_t *addr, bus_size_t count));
1153  *
1154  */
1155 static void bus_space_write_region_stream_1 __P((bus_space_tag_t,
1156 	bus_space_handle_t,
1157 	bus_size_t,
1158 	const u_int8_t *,
1159 	bus_size_t));
1160 static void bus_space_write_region_stream_2 __P((bus_space_tag_t,
1161 	bus_space_handle_t,
1162 	bus_size_t,
1163 	const u_int16_t *,
1164 	bus_size_t));
1165 static void bus_space_write_region_stream_4 __P((bus_space_tag_t,
1166 	bus_space_handle_t,
1167 	bus_size_t,
1168 	const u_int32_t *,
1169 	bus_size_t));
1170 static void bus_space_write_region_stream_8 __P((bus_space_tag_t,
1171 	bus_space_handle_t,
1172 	bus_size_t,
1173 	const u_int64_t *,
1174 	bus_size_t));
1175 static __inline__ void
1176 bus_space_write_region_stream_1(t, h, o, a, c)
1177 	bus_space_tag_t		t;
1178 	bus_space_handle_t	h;
1179 	bus_size_t		o, c;
1180 	const u_int8_t		*a;
1181 {
1182 	for (; c; a++, c--, o++)
1183 		bus_space_write_stream_1(t, h, o, *a);
1184 }
1185 
1186 static __inline__ void
1187 bus_space_write_region_stream_2(t, h, o, a, c)
1188 	bus_space_tag_t		t;
1189 	bus_space_handle_t	h;
1190 	bus_size_t		o, c;
1191 	const u_int16_t		*a;
1192 {
1193 	for (; c; a++, c--, o+=2)
1194 		bus_space_write_stream_2(t, h, o, *a);
1195 }
1196 
1197 static __inline__ void
1198 bus_space_write_region_stream_4(t, h, o, a, c)
1199 	bus_space_tag_t		t;
1200 	bus_space_handle_t	h;
1201 	bus_size_t		o, c;
1202 	const u_int32_t		*a;
1203 {
1204 	for (; c; a++, c--, o+=4)
1205 		bus_space_write_stream_4(t, h, o, *a);
1206 }
1207 
1208 static __inline__ void
1209 bus_space_write_region_stream_8(t, h, o, a, c)
1210 	bus_space_tag_t		t;
1211 	bus_space_handle_t	h;
1212 	bus_size_t		o, c;
1213 	const u_int64_t		*a;
1214 {
1215 	for (; c; a++, c--, o+=8)
1216 		bus_space_write_stream_8(t, h, o, *a);
1217 }
1218 
1219 
1220 /*
1221  *	void bus_space_set_region_stream_N __P((bus_space_tag_t tag,
1222  *	    bus_space_handle_t bsh, bus_size_t off,
1223  *	    u_intN_t *addr, bus_size_t count));
1224  *
1225  */
1226 static void bus_space_set_region_stream_1 __P((bus_space_tag_t,
1227 	bus_space_handle_t,
1228 	bus_size_t,
1229 	const u_int8_t,
1230 	bus_size_t));
1231 static void bus_space_set_region_stream_2 __P((bus_space_tag_t,
1232 	bus_space_handle_t,
1233 	bus_size_t,
1234 	const u_int16_t,
1235 	bus_size_t));
1236 static void bus_space_set_region_stream_4 __P((bus_space_tag_t,
1237 	bus_space_handle_t,
1238 	bus_size_t,
1239 	const u_int32_t,
1240 	bus_size_t));
1241 static void bus_space_set_region_stream_8 __P((bus_space_tag_t,
1242 	bus_space_handle_t,
1243 	bus_size_t,
1244 	const u_int64_t,
1245 	bus_size_t));
1246 
1247 static __inline__ void
1248 bus_space_set_region_stream_1(t, h, o, v, c)
1249 	bus_space_tag_t		t;
1250 	bus_space_handle_t	h;
1251 	bus_size_t		o, c;
1252 	const u_int8_t		v;
1253 {
1254 	for (; c; c--, o++)
1255 		bus_space_write_stream_1(t, h, o, v);
1256 }
1257 
1258 static __inline__ void
1259 bus_space_set_region_stream_2(t, h, o, v, c)
1260 	bus_space_tag_t		t;
1261 	bus_space_handle_t	h;
1262 	bus_size_t		o, c;
1263 	const u_int16_t		v;
1264 {
1265 	for (; c; c--, o+=2)
1266 		bus_space_write_stream_2(t, h, o, v);
1267 }
1268 
1269 static __inline__ void
1270 bus_space_set_region_stream_4(t, h, o, v, c)
1271 	bus_space_tag_t		t;
1272 	bus_space_handle_t	h;
1273 	bus_size_t		o, c;
1274 	const u_int32_t		v;
1275 {
1276 	for (; c; c--, o+=4)
1277 		bus_space_write_stream_4(t, h, o, v);
1278 }
1279 
1280 static __inline__ void
1281 bus_space_set_region_stream_8(t, h, o, v, c)
1282 	bus_space_tag_t		t;
1283 	bus_space_handle_t	h;
1284 	bus_size_t		o, c;
1285 	const u_int64_t		v;
1286 {
1287 	for (; c; c--, o+=8)
1288 		bus_space_write_stream_8(t, h, o, v);
1289 }
1290 
1291 
1292 /*
1293  *	void bus_space_copy_region_stream_N __P((bus_space_tag_t tag,
1294  *	    bus_space_handle_t bsh1, bus_size_t off1,
1295  *	    bus_space_handle_t bsh2, bus_size_t off2,
1296  *	    bus_size_t count));
1297  *
1298  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
1299  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
1300  */
1301 static void bus_space_copy_region_stream_1 __P((bus_space_tag_t,
1302 	bus_space_handle_t,
1303 	bus_size_t,
1304 	bus_space_handle_t,
1305 	bus_size_t,
1306 	bus_size_t));
1307 static void bus_space_copy_region_stream_2 __P((bus_space_tag_t,
1308 	bus_space_handle_t,
1309 	bus_size_t,
1310 	bus_space_handle_t,
1311 	bus_size_t,
1312 	bus_size_t));
1313 static void bus_space_copy_region_stream_4 __P((bus_space_tag_t,
1314 	bus_space_handle_t,
1315 	bus_size_t,
1316 	bus_space_handle_t,
1317 	bus_size_t,
1318 	bus_size_t));
1319 static void bus_space_copy_region_stream_8 __P((bus_space_tag_t,
1320 	bus_space_handle_t,
1321 	bus_size_t,
1322 	bus_space_handle_t,
1323 	bus_size_t,
1324 	bus_size_t));
1325 
1326 
1327 static __inline__ void
1328 bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c)
1329 	bus_space_tag_t		t;
1330 	bus_space_handle_t	h1, h2;
1331 	bus_size_t		o1, o2;
1332 	bus_size_t		c;
1333 {
1334 	for (; c; c--, o1++, o2++)
1335 	    bus_space_write_stream_1(t, h1, o1, bus_space_read_stream_1(t, h2, o2));
1336 }
1337 
1338 static __inline__ void
1339 bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c)
1340 	bus_space_tag_t		t;
1341 	bus_space_handle_t	h1, h2;
1342 	bus_size_t		o1, o2;
1343 	bus_size_t		c;
1344 {
1345 	for (; c; c--, o1+=2, o2+=2)
1346 	    bus_space_write_stream_2(t, h1, o1, bus_space_read_stream_2(t, h2, o2));
1347 }
1348 
1349 static __inline__ void
1350 bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c)
1351 	bus_space_tag_t		t;
1352 	bus_space_handle_t	h1, h2;
1353 	bus_size_t		o1, o2;
1354 	bus_size_t		c;
1355 {
1356 	for (; c; c--, o1+=4, o2+=4)
1357 	    bus_space_write_stream_4(t, h1, o1, bus_space_read_stream_4(t, h2, o2));
1358 }
1359 
1360 static __inline__ void
1361 bus_space_copy_region_stream_8(t, h1, o1, h2, o2, c)
1362 	bus_space_tag_t		t;
1363 	bus_space_handle_t	h1, h2;
1364 	bus_size_t		o1, o2;
1365 	bus_size_t		c;
1366 {
1367 	for (; c; c--, o1+=8, o2+=8)
1368 	    bus_space_write_stream_8(t, h1, o1, bus_space_read_8(t, h2, o2));
1369 }
1370 
1371 
1372 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
1373 
1374 /*
1375  * Flags used in various bus DMA methods.
1376  */
1377 #define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
1378 #define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
1379 #define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
1380 #define	BUS_DMA_COHERENT	0x004	/* hint: map memory DMA coherent */
1381 #define	BUS_DMA_NOWRITE		0x008	/* I suppose the following two should default on */
1382 #define	BUS_DMA_BUS1		0x010
1383 #define	BUS_DMA_BUS2		0x020
1384 #define	BUS_DMA_BUS3		0x040
1385 #define	BUS_DMA_BUS4		0x080
1386 #define	BUS_DMA_STREAMING	0x100	/* hint: sequential, unidirectional */
1387 #define	BUS_DMA_READ		0x200	/* mapping is device -> memory only */
1388 #define	BUS_DMA_WRITE		0x400	/* mapping is memory -> device only */
1389 
1390 
1391 #define	BUS_DMA_NOCACHE		BUS_DMA_BUS1
1392 #define	BUS_DMA_DVMA		BUS_DMA_BUS2	/* Don't bother with alignment */
1393 
1394 /* Forwards needed by prototypes below. */
1395 struct mbuf;
1396 struct uio;
1397 
1398 /*
1399  * Operations performed by bus_dmamap_sync().
1400  */
1401 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
1402 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
1403 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
1404 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
1405 
1406 typedef struct sparc_bus_dma_tag	*bus_dma_tag_t;
1407 typedef struct sparc_bus_dmamap		*bus_dmamap_t;
1408 
1409 /*
1410  *	bus_dma_segment_t
1411  *
1412  *	Describes a single contiguous DMA transaction.  Values
1413  *	are suitable for programming into DMA registers.
1414  */
1415 struct sparc_bus_dma_segment {
1416 	bus_addr_t	ds_addr;	/* DVMA address */
1417 	bus_size_t	ds_len;		/* length of transfer */
1418 	bus_size_t	_ds_boundary;	/* don't cross this */
1419 	bus_size_t	_ds_align;	/* align to this */
1420 	void		*_ds_mlist;	/* XXX - dmamap_alloc'ed pages */
1421 };
1422 typedef struct sparc_bus_dma_segment	bus_dma_segment_t;
1423 
1424 
1425 /*
1426  *	bus_dma_tag_t
1427  *
1428  *	A machine-dependent opaque type describing the implementation of
1429  *	DMA for a given bus.
1430  */
1431 struct sparc_bus_dma_tag {
1432 	void	*_cookie;		/* cookie used in the guts */
1433 	struct sparc_bus_dma_tag* _parent;
1434 
1435 	/*
1436 	 * DMA mapping methods.
1437 	 */
1438 	int	(*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
1439 		    bus_size_t, bus_size_t, int, bus_dmamap_t *));
1440 	void	(*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
1441 	int	(*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
1442 		    bus_size_t, struct proc *, int));
1443 	int	(*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
1444 		    struct mbuf *, int));
1445 	int	(*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
1446 		    struct uio *, int));
1447 	int	(*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
1448 		    bus_dma_segment_t *, int, bus_size_t, int));
1449 	void	(*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
1450 	void	(*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
1451 		    bus_addr_t, bus_size_t, int));
1452 
1453 	/*
1454 	 * DMA memory utility functions.
1455 	 */
1456 	int	(*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
1457 		    bus_size_t, bus_dma_segment_t *, int, int *, int));
1458 	void	(*_dmamem_free) __P((bus_dma_tag_t,
1459 		    bus_dma_segment_t *, int));
1460 	int	(*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
1461 		    int, size_t, caddr_t *, int));
1462 	void	(*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
1463 	paddr_t	(*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
1464 		    int, off_t, int, int));
1465 };
1466 
1467 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
1468 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
1469 #define	bus_dmamap_destroy(t, p)				\
1470 	(*(t)->_dmamap_destroy)((t), (p))
1471 #define	bus_dmamap_load(t, m, b, s, p, f)			\
1472 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
1473 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
1474 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
1475 #define	bus_dmamap_load_uio(t, m, u, f)				\
1476 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
1477 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
1478 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
1479 #define	bus_dmamap_unload(t, p)					\
1480 	(*(t)->_dmamap_unload)((t), (p))
1481 #define	bus_dmamap_sync(t, p, o, l, ops)			\
1482 	(void)((t)->_dmamap_sync ?				\
1483 	    (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
1484 
1485 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
1486 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
1487 #define	bus_dmamem_free(t, sg, n)				\
1488 	(*(t)->_dmamem_free)((t), (sg), (n))
1489 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
1490 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
1491 #define	bus_dmamem_unmap(t, k, s)				\
1492 	(*(t)->_dmamem_unmap)((t), (k), (s))
1493 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
1494 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
1495 
1496 /*
1497  *	bus_dmamap_t
1498  *
1499  *	Describes a DMA mapping.
1500  */
1501 struct sparc_bus_dmamap {
1502 	/*
1503 	 * PRIVATE MEMBERS: not for use my machine-independent code.
1504 	 */
1505 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
1506 	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
1507 	bus_size_t	_dm_boundary;	/* don't cross this */
1508 	int		_dm_segcnt;	/* number of segs this map can map */
1509 	int		_dm_flags;	/* misc. flags */
1510 #define _DM_TYPE_LOAD	0
1511 #define _DM_TYPE_SEGS	1
1512 #define _DM_TYPE_UIO	2
1513 #define _DM_TYPE_MBUF	3
1514 	int		_dm_type;	/* type of mapping: raw, uio, mbuf, etc */
1515 	void		*_dm_source;	/* source mbuf, uio, etc. needed for unload *///////////////////////
1516 
1517 	void		*_dm_cookie;	/* cookie for bus-specific functions */
1518 
1519 	/*
1520 	 * PUBLIC MEMBERS: these are used by machine-independent code.
1521 	 */
1522 	bus_size_t	dm_mapsize;	/* size of the mapping */
1523 	int		dm_nsegs;	/* # valid segments in mapping */
1524 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
1525 };
1526 
1527 #ifdef _SPARC_BUS_DMA_PRIVATE
1528 int	_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
1529 	    bus_size_t, int, bus_dmamap_t *));
1530 void	_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
1531 int	_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
1532 	    bus_size_t, struct proc *, int));
1533 int	_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
1534 	    struct mbuf *, int));
1535 int	_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
1536 	    struct uio *, int));
1537 int	_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
1538 	    bus_dma_segment_t *, int, bus_size_t, int));
1539 void	_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
1540 void	_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
1541 	    bus_size_t, int));
1542 
1543 int	_bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
1544 	    bus_size_t alignment, bus_size_t boundary,
1545 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
1546 void	_bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1547 	    int nsegs));
1548 int	_bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1549 	    int nsegs, size_t size, caddr_t *kvap, int flags));
1550 void	_bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
1551 	    size_t size));
1552 paddr_t	_bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1553 	    int nsegs, off_t off, int prot, int flags));
1554 
1555 int	_bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
1556 	    bus_size_t alignment, bus_size_t boundary,
1557 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
1558 	    vaddr_t low, vaddr_t high));
1559 #endif /* _SPARC_BUS_DMA_PRIVATE */
1560 
1561 #endif /* _SPARC_BUS_H_ */
1562