xref: /netbsd-src/sys/arch/sh3/include/bus_funcs.h (revision 1b9578b8c2c1f848eeb16dabbfd7d1f0d9fdefbd)
1 /*	$NetBSD: bus_funcs.h,v 1.1 2011/07/01 17:10:01 dyoung Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
35  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. All advertising materials mentioning features or use of this software
46  *    must display the following acknowledgement:
47  *      This product includes software developed by Christopher G. Demetriou
48  *	for the NetBSD Project.
49  * 4. The name of the author may not be used to endorse or promote products
50  *    derived from this software without specific prior written permission
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63 
64 #ifndef _SH3_BUS_FUNCS_H_
65 #define	_SH3_BUS_FUNCS_H_
66 
67 int bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t size,
68     int, bus_space_handle_t *);
69 
70 #ifdef SH4_PCMCIA
71 int shpcmcia_memio_map(bus_space_tag_t, bus_addr_t, bus_size_t size,
72     int, bus_space_handle_t *);
73 
74 int shpcmcia_mem_add_mapping(bus_addr_t, bus_size_t, int,
75     bus_space_handle_t *);
76 void shpcmcia_memio_unmap(bus_space_tag_t, bus_space_handle_t,
77     bus_size_t);
78 void shpcmcia_memio_free(bus_space_tag_t, bus_space_handle_t,
79     bus_size_t);
80 int shpcmcia_memio_subregion(bus_space_tag_t, bus_space_handle_t,
81     bus_size_t, bus_size_t, bus_space_handle_t *);
82 #endif
83 
84 /*
85  *	u_intN_t bus_space_read_N(bus_space_tag_t tag,
86  *	    bus_space_handle_t bsh, bus_size_t offset);
87  *
88  * Read a 1, 2, 4, or 8 byte quantity from bus space
89  * described by tag/handle/offset.
90  */
91 static __inline uint8_t bus_space_read_1
92 	(bus_space_tag_t, bus_space_handle_t, bus_size_t);
93 static __inline uint16_t bus_space_read_2
94 	(bus_space_tag_t, bus_space_handle_t, bus_size_t);
95 static __inline uint32_t bus_space_read_4
96 	(bus_space_tag_t, bus_space_handle_t, bus_size_t);
97 
98 uint8_t
99 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t bsh,
100     bus_size_t offset)
101 {
102 
103 	return *(volatile uint8_t *)(bsh + offset);
104 }
105 
106 uint16_t
107 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t bsh,
108     bus_size_t offset)
109 {
110 
111 	return bswap16(*(volatile uint16_t *)(bsh + offset));
112 }
113 
114 uint32_t
115 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t bsh,
116     bus_size_t offset)
117 {
118 
119 	return bswap32(*(volatile uint32_t *)(bsh + offset));
120 }
121 
122 static __inline uint16_t bus_space_read_stream_2
123 	(bus_space_tag_t, bus_space_handle_t, bus_size_t);
124 
125 static __inline uint32_t bus_space_read_stream_4
126 	(bus_space_tag_t, bus_space_handle_t, bus_size_t);
127 
128 uint16_t
129 bus_space_read_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
130     bus_size_t offset)
131 {
132 
133 	return *(volatile uint16_t *)(bsh + offset);
134 }
135 
136 uint32_t
137 bus_space_read_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
138     bus_size_t offset)
139 {
140 
141 	return *(volatile uint32_t *)(bsh + offset);
142 }
143 
144 /*
145  *	void bus_space_read_multi_N(bus_space_tag_t tag,
146  *	    bus_space_handle_t bsh, bus_size_t offset,
147  *	    u_intN_t *addr, size_t count);
148  *
149  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
150  * described by tag/handle/offset and copy into buffer provided.
151  */
152 static __inline void bus_space_read_multi_1(bus_space_tag_t,
153     bus_space_handle_t, bus_size_t, uint8_t *, bus_size_t);
154 static __inline void bus_space_read_multi_2(bus_space_tag_t,
155     bus_space_handle_t, bus_size_t, uint16_t *, bus_size_t);
156 static __inline void bus_space_read_multi_4(bus_space_tag_t,
157     bus_space_handle_t, bus_size_t, uint32_t *, bus_size_t);
158 
159 void
160 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
161     bus_size_t offset, uint8_t *addr, bus_size_t count)
162 {
163 
164 	while (count--)
165 		*addr++ = bus_space_read_1(tag, bsh, offset);
166 }
167 
168 void
169 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
170     bus_size_t offset, uint16_t *addr, bus_size_t count)
171 {
172 
173 	while (count--)
174 		*addr++ = bus_space_read_2(tag, bsh, offset);
175 }
176 
177 void
178 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
179     bus_size_t offset, uint32_t *addr, bus_size_t count)
180 {
181 
182 	while (count--)
183 		*addr++ = bus_space_read_4(tag, bsh, offset);
184 }
185 
186 static __inline void bus_space_read_multi_stream_2(bus_space_tag_t,
187     bus_space_handle_t, bus_size_t, uint16_t *, bus_size_t);
188 static __inline void bus_space_read_multi_stream_4(bus_space_tag_t,
189     bus_space_handle_t, bus_size_t, uint32_t *, bus_size_t);
190 
191 void
192 bus_space_read_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
193     bus_size_t offset, uint16_t *addr, bus_size_t count)
194 {
195 
196 	while (count--)
197 		*addr++ = *(volatile uint16_t *)(bsh + offset);
198 }
199 
200 void
201 bus_space_read_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
202     bus_size_t offset, uint32_t *addr, bus_size_t count)
203 {
204 
205 	while (count--)
206 		*addr++ = *(volatile uint32_t *)(bsh + offset);
207 }
208 
209 /*
210  *	int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
211  *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
212  *	    bus_size_t boundary, int flags, bus_addr_t *addrp,
213  *	    bus_space_handle_t *bshp);
214  *
215  * Allocate a region of bus space.
216  */
217 int sh_memio_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t,
218     bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
219 
220 #define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)			\
221 	sh_memio_alloc((t), (rs), (re), (s), (a), (b), (f), (ap), (hp))
222 
223 /*
224  *	int bus_space_free(bus_space_tag_t t,
225  *	    bus_space_handle_t bsh, bus_size_t size);
226  *
227  * Free a region of bus space.
228  */
229 void sh_memio_free(bus_space_tag_t, bus_space_handle_t, bus_size_t);
230 
231 #define	bus_space_free(t, h, s)						\
232 	sh_memio_free((t), (h), (s))
233 
234 /*
235  *	int bus_space_unmap(bus_space_tag_t t,
236  *	    bus_space_handle_t bsh, bus_size_t size);
237  *
238  * Unmap a region of bus space.
239  */
240 void sh_memio_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
241 
242 #define	bus_space_unmap(t, h, s)					\
243 	sh_memio_unmap((t), (h), (s))
244 
245 /*
246  *	int bus_space_subregion(bus_space_tag_t t,
247  *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
248  *	    bus_space_handle_t *nbshp);
249  *
250  * Get a new handle for a subregion of an already-mapped area of bus space.
251  */
252 int sh_memio_subregion(bus_space_tag_t, bus_space_handle_t,
253     bus_size_t, bus_size_t, bus_space_handle_t *);
254 
255 #define	bus_space_subregion(t, h, o, s, nhp)				\
256 	sh_memio_subregion((t), (h), (o), (s), (nhp))
257 
258 /*
259  *	void bus_space_read_region_N(bus_space_tag_t tag,
260  *	    bus_space_handle_t bsh, bus_size_t offset,
261  *	    u_intN_t *addr, size_t count);
262  *
263  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
264  * described by tag/handle and starting at `offset' and copy into
265  * buffer provided.
266  */
267 static __inline void bus_space_read_region_1(bus_space_tag_t,
268     bus_space_handle_t, bus_size_t, uint8_t *, bus_size_t);
269 static __inline void bus_space_read_region_2(bus_space_tag_t,
270     bus_space_handle_t, bus_size_t, uint16_t *, bus_size_t);
271 static __inline void bus_space_read_region_4(bus_space_tag_t,
272     bus_space_handle_t, bus_size_t, uint32_t *, bus_size_t);
273 
274 void
275 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
276     bus_size_t offset, uint8_t *addr, bus_size_t count)
277 {
278 	uint8_t *p = (uint8_t *)(bsh + offset);
279 
280 	while (count--)
281 		*addr++ = *p++;
282 }
283 
284 void
285 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
286     bus_size_t offset, uint16_t *addr, bus_size_t count)
287 {
288 	uint16_t *p = (uint16_t *)(bsh + offset);
289 
290 	while (count--)
291 		*addr++ = bswap16(*p++);
292 }
293 
294 void
295 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
296     bus_size_t offset, uint32_t *addr, bus_size_t count)
297 {
298 	uint32_t *p = (uint32_t *)(bsh + offset);
299 
300 	while (count--)
301 		*addr++ = bswap32(*p++);
302 }
303 
304 /*
305  *	void bus_space_read_region_stream_N(bus_space_tag_t tag,
306  *	    bus_space_handle_t bsh, bus_size_t offset,
307  *	    u_intN_t *addr, size_t count);
308  *
309  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
310  * described by tag/handle and starting at `offset' and copy into
311  * buffer provided.
312  */
313 static __inline void bus_space_read_region_stream_1(bus_space_tag_t,
314     bus_space_handle_t, bus_size_t, uint8_t *, bus_size_t);
315 static __inline void bus_space_read_region_stream_2(bus_space_tag_t,
316     bus_space_handle_t, bus_size_t, uint16_t *, bus_size_t);
317 static __inline void bus_space_read_region_stream_4(bus_space_tag_t,
318     bus_space_handle_t, bus_size_t, uint32_t *, bus_size_t);
319 
320 void
321 bus_space_read_region_stream_1(bus_space_tag_t tag, bus_space_handle_t bsh,
322     bus_size_t offset, uint8_t *addr, bus_size_t count)
323 {
324 	uint8_t *p = (uint8_t *)(bsh + offset);
325 
326 	while (count--)
327 		*addr++ = *p++;
328 }
329 
330 void
331 bus_space_read_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
332     bus_size_t offset, uint16_t *addr, bus_size_t count)
333 {
334 	uint16_t *p = (uint16_t *)(bsh + offset);
335 
336 	while (count--)
337 		*addr++ = *p++;
338 }
339 
340 void
341 bus_space_read_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
342     bus_size_t offset, uint32_t *addr, bus_size_t count)
343 {
344 	uint32_t *p = (uint32_t *)(bsh + offset);
345 
346 	while (count--)
347 		*addr++ = *p++;
348 }
349 
350 /*
351  *	void bus_space_write_region_N(bus_space_tag_t tag,
352  *	    bus_space_handle_t bsh, bus_size_t offset,
353  *	    const u_intN_t *addr, size_t count);
354  *
355  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
356  * to bus space described by tag/handle starting at `offset'.
357  */
358 static __inline void bus_space_write_region_1(bus_space_tag_t,
359     bus_space_handle_t, bus_size_t, const uint8_t *, bus_size_t);
360 static __inline void bus_space_write_region_2(bus_space_tag_t,
361     bus_space_handle_t, bus_size_t, const uint16_t *, bus_size_t);
362 static __inline void bus_space_write_region_4(bus_space_tag_t,
363     bus_space_handle_t, bus_size_t, const uint32_t *, bus_size_t);
364 
365 void
366 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
367     bus_size_t offset, const uint8_t *addr, bus_size_t count)
368 {
369 	uint8_t *p = (uint8_t *)(bsh + offset);
370 
371 	while (count--)
372 		*p++ = *addr++;
373 }
374 
375 void
376 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
377     bus_size_t offset, const uint16_t *addr, bus_size_t count)
378 {
379 	uint16_t *p = (uint16_t *)(bsh + offset);
380 
381 	while (count--)
382 		*p++ = bswap16(*addr++);
383 }
384 
385 void
386 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
387     bus_size_t offset, const uint32_t *addr, bus_size_t count)
388 {
389 	uint32_t *p = (uint32_t *)(bsh + offset);
390 
391 	while (count--)
392 		*p++ = bswap32(*addr++);
393 }
394 
395 /*
396  *	void bus_space_write_region_stream_N(bus_space_tag_t tag,
397  *	    bus_space_handle_t bsh, bus_size_t offset,
398  *	    const u_intN_t *addr, size_t count);
399  *
400  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
401  * to bus space described by tag/handle starting at `offset'.
402  */
403 static __inline void bus_space_write_region_stream_1(bus_space_tag_t,
404     bus_space_handle_t, bus_size_t, const uint8_t *, bus_size_t);
405 static __inline void bus_space_write_region_stream_2(bus_space_tag_t,
406     bus_space_handle_t, bus_size_t, const uint16_t *, bus_size_t);
407 static __inline void bus_space_write_region_stream_4(bus_space_tag_t,
408     bus_space_handle_t, bus_size_t, const uint32_t *, bus_size_t);
409 
410 void
411 bus_space_write_region_stream_1(bus_space_tag_t tag, bus_space_handle_t bsh,
412     bus_size_t offset, const uint8_t *addr, bus_size_t count)
413 {
414 	uint8_t *p = (uint8_t *)(bsh + offset);
415 
416 	while (count--)
417 		*p++ = *addr++;
418 }
419 
420 void
421 bus_space_write_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
422     bus_size_t offset, const uint16_t *addr, bus_size_t count)
423 {
424 	uint16_t *p = (uint16_t *)(bsh + offset);
425 
426 	while (count--)
427 		*p++ = *addr++;
428 }
429 
430 void
431 bus_space_write_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
432     bus_size_t offset, const uint32_t *addr, bus_size_t count)
433 {
434 	uint32_t *p = (uint32_t *)(bsh + offset);
435 
436 	while (count--)
437 		*p++ = *addr++;
438 }
439 
440 /*
441  *	void bus_space_write_N(bus_space_tag_t tag,
442  *	    bus_space_handle_t bsh, bus_size_t offset,
443  *	    u_intN_t value);
444  *
445  * Write the 1, 2, 4, or 8 byte value `value' to bus space
446  * described by tag/handle/offset.
447  */
448 static __inline void bus_space_write_1(bus_space_tag_t,
449     bus_space_handle_t, bus_size_t, uint8_t);
450 static __inline void bus_space_write_2(bus_space_tag_t,
451     bus_space_handle_t, bus_size_t, uint16_t);
452 static __inline void bus_space_write_4(bus_space_tag_t,
453     bus_space_handle_t, bus_size_t, uint32_t);
454 
455 void
456 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
457     bus_size_t offset, uint8_t value)
458 {
459 
460 	*(volatile uint8_t *)(bsh + offset) = value;
461 }
462 
463 void
464 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
465     bus_size_t offset, uint16_t value)
466 {
467 
468 	*(volatile uint16_t *)(bsh + offset) = bswap16(value);
469 }
470 
471 void
472 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
473     bus_size_t offset, uint32_t value)
474 {
475 
476 	*(volatile uint32_t *)(bsh + offset) = bswap32(value);
477 }
478 
479 static __inline void bus_space_write_stream_2(bus_space_tag_t,
480     bus_space_handle_t, bus_size_t, uint16_t);
481 static __inline void bus_space_write_stream_4(bus_space_tag_t,
482     bus_space_handle_t, bus_size_t, uint32_t);
483 
484 void
485 bus_space_write_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
486     bus_size_t offset, uint16_t value)
487 {
488 
489 	*(volatile uint16_t *)(bsh + offset) = value;
490 }
491 
492 void
493 bus_space_write_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
494     bus_size_t offset, uint32_t value)
495 {
496 
497 	*(volatile uint32_t *)(bsh + offset) = value;
498 }
499 
500 /*
501  *	void bus_space_write_multi_N(bus_space_tag_t tag,
502  *	    bus_space_handle_t bsh, bus_size_t offset,
503  *	    const u_intN_t *addr, size_t count);
504  *
505  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
506  * provided to bus space described by tag/handle/offset.
507  */
508 static __inline void bus_space_write_multi_1(bus_space_tag_t,
509     bus_space_handle_t, bus_size_t, const uint8_t *, bus_size_t);
510 static __inline void bus_space_write_multi_2(bus_space_tag_t,
511     bus_space_handle_t, bus_size_t, const uint16_t *, bus_size_t);
512 static __inline void bus_space_write_multi_4(bus_space_tag_t,
513     bus_space_handle_t, bus_size_t, const uint32_t *, bus_size_t);
514 
515 void
516 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
517     bus_size_t offset, const uint8_t *addr, bus_size_t count)
518 {
519 
520 	while (count--)
521 		bus_space_write_1(tag, bsh, offset, *addr++);
522 }
523 
524 void
525 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
526     bus_size_t offset, const uint16_t *addr, bus_size_t count)
527 {
528 
529 	while (count--)
530 		bus_space_write_2(tag, bsh, offset, *addr++);
531 }
532 
533 void
534 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
535     bus_size_t offset, const uint32_t *addr, bus_size_t count)
536 {
537 
538 	while (count--)
539 		bus_space_write_4(tag, bsh, offset, *addr++);
540 }
541 
542 static __inline void bus_space_write_multi_stream_2(bus_space_tag_t,
543     bus_space_handle_t, bus_size_t, const uint16_t *, bus_size_t);
544 static __inline void bus_space_write_multi_stream_4(bus_space_tag_t,
545     bus_space_handle_t, bus_size_t, const uint32_t *, bus_size_t);
546 
547 void
548 bus_space_write_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
549     bus_size_t offset, const uint16_t *addr, bus_size_t count)
550 {
551 
552 	while (count--)
553 		bus_space_write_stream_2(tag, bsh, offset, *addr++);
554 }
555 
556 void
557 bus_space_write_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
558     bus_size_t offset, const uint32_t *addr, bus_size_t count)
559 {
560 
561 	while (count--)
562 		bus_space_write_stream_4(tag, bsh, offset, *addr++);
563 }
564 
565 /*
566  *	void bus_space_set_multi_N(bus_space_tag_t tag,
567  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
568  *	    size_t count);
569  *
570  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
571  * by tag/handle/offset `count' times.
572  */
573 static __inline void bus_space_set_multi_1(bus_space_tag_t,
574     bus_space_handle_t, bus_size_t, uint8_t, size_t);
575 static __inline void bus_space_set_multi_2(bus_space_tag_t,
576     bus_space_handle_t, bus_size_t, uint16_t, size_t);
577 static __inline void bus_space_set_multi_4(bus_space_tag_t,
578     bus_space_handle_t, bus_size_t, uint32_t, size_t);
579 
580 void
581 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
582     bus_size_t offset, uint8_t val, size_t count)
583 {
584 
585 	while (count--)
586 		bus_space_write_1(tag, bsh, offset, val);
587 }
588 
589 void
590 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
591     bus_size_t offset, uint16_t val, size_t count)
592 {
593 
594 	while (count--)
595 		bus_space_write_2(tag, bsh, offset, val);
596 }
597 
598 void
599 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
600     bus_size_t offset, uint32_t val, size_t count)
601 {
602 
603 	while (count--)
604 		bus_space_write_4(tag, bsh, offset, val);
605 }
606 
607 /*
608  *	void bus_space_set_region_N(bus_space_tag_t tag,
609  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
610  *	    size_t count);
611  *
612  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
613  * by tag/handle starting at `offset'.
614  */
615 static __inline void bus_space_set_region_1(bus_space_tag_t,
616     bus_space_handle_t, bus_size_t, uint8_t, size_t);
617 static __inline void bus_space_set_region_2(bus_space_tag_t,
618     bus_space_handle_t, bus_size_t, uint16_t, size_t);
619 static __inline void bus_space_set_region_4(bus_space_tag_t,
620     bus_space_handle_t, bus_size_t, uint32_t, size_t);
621 
622 void
623 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
624     bus_size_t offset, uint8_t val, size_t count)
625 {
626 	volatile uint8_t *addr = (void *)(bsh + offset);
627 
628 	while (count--)
629 		*addr++ = val;
630 }
631 
632 void
633 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
634     bus_size_t offset, uint16_t val, size_t count)
635 {
636 	volatile uint16_t *addr = (void *)(bsh + offset);
637 
638 	val = bswap16(val);
639 	while (count--)
640 		*addr++ = val;
641 }
642 
643 void
644 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
645     bus_size_t offset, uint32_t val, size_t count)
646 {
647 	volatile uint32_t *addr = (void *)(bsh + offset);
648 
649 	val = bswap32(val);
650 	while (count--)
651 		*addr++ = val;
652 }
653 
654 /*
655  *	void bus_space_set_region_stream_N(bus_space_tag_t tag,
656  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
657  *	    size_t count);
658  *
659  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
660  * by tag/handle starting at `offset'.
661  */
662 static __inline void bus_space_set_region_stream_1(bus_space_tag_t,
663     bus_space_handle_t, bus_size_t, uint8_t, bus_size_t);
664 static __inline void bus_space_set_region_stream_2(bus_space_tag_t,
665     bus_space_handle_t, bus_size_t, uint16_t, bus_size_t);
666 static __inline void bus_space_set_region_stream_4(bus_space_tag_t,
667     bus_space_handle_t, bus_size_t, uint32_t, bus_size_t);
668 
669 void
670 bus_space_set_region_stream_1(bus_space_tag_t tag, bus_space_handle_t bsh,
671     bus_size_t offset, uint8_t val, bus_size_t count)
672 {
673 	volatile uint8_t *addr = (void *)(bsh + offset);
674 
675 	while (count--)
676 		*addr++ = val;
677 }
678 
679 void
680 bus_space_set_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
681     bus_size_t offset, uint16_t val, bus_size_t count)
682 {
683 	volatile uint16_t *addr = (void *)(bsh + offset);
684 
685 	while (count--)
686 		*addr++ = val;
687 }
688 
689 void
690 bus_space_set_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
691     bus_size_t offset, uint32_t val, bus_size_t count)
692 {
693 	volatile uint32_t *addr = (void *)(bsh + offset);
694 
695 	while (count--)
696 		*addr++ = val;
697 }
698 
699 /*
700  *	void bus_space_copy_region_N(bus_space_tag_t tag,
701  *	    bus_space_handle_t bsh1, bus_size_t off1,
702  *	    bus_space_handle_t bsh2, bus_size_t off2,
703  *	    size_t count);
704  *
705  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
706  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
707  */
708 static __inline void bus_space_copy_region_1(bus_space_tag_t,
709     bus_space_handle_t, bus_size_t, bus_space_handle_t, bus_size_t,
710     size_t);
711 static __inline void bus_space_copy_region_2(bus_space_tag_t,
712     bus_space_handle_t, bus_size_t, bus_space_handle_t, bus_size_t,
713     size_t);
714 static __inline void bus_space_copy_region_4(bus_space_tag_t,
715     bus_space_handle_t, bus_size_t, bus_space_handle_t, bus_size_t,
716     size_t);
717 
718 void
719 bus_space_copy_region_1(bus_space_tag_t t, bus_space_handle_t h1,
720     bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, size_t c)
721 {
722 	volatile uint8_t *addr1 = (void *)(h1 + o1);
723 	volatile uint8_t *addr2 = (void *)(h2 + o2);
724 
725 	if (addr1 >= addr2) {	/* src after dest: copy forward */
726 		while (c--)
727 			*addr2++ = *addr1++;
728 	} else {		/* dest after src: copy backwards */
729 		addr1 += c - 1;
730 		addr2 += c - 1;
731 		while (c--)
732 			*addr2-- = *addr1--;
733 	}
734 }
735 
736 void
737 bus_space_copy_region_2(bus_space_tag_t t, bus_space_handle_t h1,
738     bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, size_t c)
739 {
740 	volatile uint16_t *addr1 = (void *)(h1 + o1);
741 	volatile uint16_t *addr2 = (void *)(h2 + o2);
742 
743 	if (addr1 >= addr2) {	/* src after dest: copy forward */
744 		while (c--)
745 			*addr2++ = *addr1++;
746 	} else {		/* dest after src: copy backwards */
747 		addr1 += c - 1;
748 		addr2 += c - 1;
749 		while (c--)
750 			*addr2-- = *addr1--;
751 	}
752 }
753 
754 void
755 bus_space_copy_region_4(bus_space_tag_t t, bus_space_handle_t h1,
756     bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, size_t c)
757 {
758 	volatile uint32_t *addr1 = (void *)(h1 + o1);
759 	volatile uint32_t *addr2 = (void *)(h2 + o2);
760 
761 	if (addr1 >= addr2) {	/* src after dest: copy forward */
762 		while (c--)
763 			*addr2++ = *addr1++;
764 	} else {		/* dest after src: copy backwards */
765 		addr1 += c - 1;
766 		addr2 += c - 1;
767 		while (c--)
768 			*addr2-- = *addr1--;
769 	}
770 }
771 
772 /*
773  * Bus read/write barrier methods.
774  *
775  *	void bus_space_barrier(bus_space_tag_t tag,
776  *	    bus_space_handle_t bsh, bus_size_t offset,
777  *	    bus_size_t len, int flags);
778  *
779  * Note: the sh3 does not currently require barriers, but we must
780  * provide the flags to MI code.
781  */
782 #define	bus_space_barrier(t, h, o, l, f)	\
783 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
784 
785 #endif /* _SH3_BUS_FUNCS_H_ */
786