xref: /freebsd-13-stable/sys/x86/include/bus.h (revision f8167e0404dab9ffeaca95853dd237ab7c587f82)
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause AND BSD-2-ClauseE
3  *
4  * Copyright (c) KATO Takenori, 1999.
5  *
6  * All rights reserved.  Unpublished rights reserved under the copyright
7  * laws of Japan.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer as
15  *    the first lines of this file unmodified.
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. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*	$NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $	*/
35 
36 /*-
37  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
38  * All rights reserved.
39  *
40  * This code is derived from software contributed to The NetBSD Foundation
41  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
42  * NASA Ames Research Center.
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  *
53  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
54  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
55  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
57  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
58  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
59  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
61  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
62  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
63  * POSSIBILITY OF SUCH DAMAGE.
64  */
65 
66 /*-
67  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
68  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
69  *
70  * Redistribution and use in source and binary forms, with or without
71  * modification, are permitted provided that the following conditions
72  * are met:
73  * 1. Redistributions of source code must retain the above copyright
74  *    notice, this list of conditions and the following disclaimer.
75  * 2. Redistributions in binary form must reproduce the above copyright
76  *    notice, this list of conditions and the following disclaimer in the
77  *    documentation and/or other materials provided with the distribution.
78  * 3. All advertising materials mentioning features or use of this software
79  *    must display the following acknowledgement:
80  *      This product includes software developed by Christopher G. Demetriou
81  *	for the NetBSD Project.
82  * 4. The name of the author may not be used to endorse or promote products
83  *    derived from this software without specific prior written permission
84  *
85  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
86  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
87  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
88  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
89  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
90  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
91  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
92  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
94  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95  */
96 
97 #ifndef _MACHINE_BUS_H_
98 #define _MACHINE_BUS_H_
99 
100 #include <machine/_bus.h>
101 #include <machine/cpufunc.h>
102 #include <machine/bus_dma.h>
103 
104 #ifndef __GNUCLIKE_ASM
105 #error "no assembler code for your compiler"
106 #endif
107 
108 /*
109  * Values for the x86 bus space tag, not to be used directly by MI code.
110  */
111 #define	X86_BUS_SPACE_IO	0	/* space is i/o space */
112 #define	X86_BUS_SPACE_MEM	1	/* space is mem space */
113 
114 #define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
115 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
116 #if defined(__amd64__)
117 #define BUS_SPACE_MAXSIZE	0xFFFFFFFFFFFFFFFFULL
118 #else
119 #define BUS_SPACE_MAXSIZE	0xFFFFFFFF
120 #endif
121 #define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
122 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
123 #if defined(__amd64__) || defined(PAE)
124 #define BUS_SPACE_MAXADDR_48BIT	0xFFFFFFFFFFFFULL
125 #define BUS_SPACE_MAXADDR	0xFFFFFFFFFFFFFFFFULL
126 #else
127 #define BUS_SPACE_MAXADDR	0xFFFFFFFF
128 #endif
129 
130 #define BUS_SPACE_INVALID_DATA	(~0)
131 #define BUS_SPACE_UNRESTRICTED	(~0)
132 
133 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
134 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
135 
136 #if defined(SAN_NEEDS_INTERCEPTORS) && !defined(SAN_RUNTIME)
137 #include <sys/bus_san.h>
138 #else
139 
140 /*
141  * Map a region of device bus space into CPU virtual address space.
142  */
143 
144 int bus_space_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size,
145     int flags, bus_space_handle_t *bshp);
146 
147 /*
148  * Unmap a region of device bus space.
149  */
150 
151 void bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t bsh,
152     bus_size_t size);
153 
154 /*
155  * Get a new handle for a subregion of an already-mapped area of bus space.
156  */
157 
158 static __inline int bus_space_subregion(bus_space_tag_t t,
159 					bus_space_handle_t bsh,
160 					bus_size_t offset, bus_size_t size,
161 					bus_space_handle_t *nbshp);
162 
163 static __inline int
bus_space_subregion(bus_space_tag_t t __unused,bus_space_handle_t bsh,bus_size_t offset,bus_size_t size __unused,bus_space_handle_t * nbshp)164 bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
165 		    bus_size_t offset, bus_size_t size __unused,
166 		    bus_space_handle_t *nbshp)
167 {
168 
169 	*nbshp = bsh + offset;
170 	return (0);
171 }
172 
173 /*
174  * Allocate a region of memory that is accessible to devices in bus space.
175  */
176 
177 int	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
178 			bus_addr_t rend, bus_size_t size, bus_size_t align,
179 			bus_size_t boundary, int flags, bus_addr_t *addrp,
180 			bus_space_handle_t *bshp);
181 
182 /*
183  * Free a region of bus space accessible memory.
184  */
185 
186 static __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
187 				    bus_size_t size);
188 
189 static __inline void
bus_space_free(bus_space_tag_t t __unused,bus_space_handle_t bsh __unused,bus_size_t size __unused)190 bus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
191 	       bus_size_t size __unused)
192 {
193 }
194 
195 /*
196  * Read a 1, 2, 4, or 8 byte quantity from bus space
197  * described by tag/handle/offset.
198  */
199 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
200 					  bus_space_handle_t handle,
201 					  bus_size_t offset);
202 
203 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
204 					   bus_space_handle_t handle,
205 					   bus_size_t offset);
206 
207 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
208 					   bus_space_handle_t handle,
209 					   bus_size_t offset);
210 
211 #ifdef __amd64__
212 static __inline uint64_t bus_space_read_8(bus_space_tag_t tag,
213 					  bus_space_handle_t handle,
214 					  bus_size_t offset);
215 #endif
216 
217 static __inline u_int8_t
bus_space_read_1(bus_space_tag_t tag,bus_space_handle_t handle,bus_size_t offset)218 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
219 		 bus_size_t offset)
220 {
221 
222 	if (tag == X86_BUS_SPACE_IO)
223 		return (inb(handle + offset));
224 	return (*(volatile u_int8_t *)(handle + offset));
225 }
226 
227 static __inline u_int16_t
bus_space_read_2(bus_space_tag_t tag,bus_space_handle_t handle,bus_size_t offset)228 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
229 		 bus_size_t offset)
230 {
231 
232 	if (tag == X86_BUS_SPACE_IO)
233 		return (inw(handle + offset));
234 	return (*(volatile u_int16_t *)(handle + offset));
235 }
236 
237 static __inline u_int32_t
bus_space_read_4(bus_space_tag_t tag,bus_space_handle_t handle,bus_size_t offset)238 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
239 		 bus_size_t offset)
240 {
241 
242 	if (tag == X86_BUS_SPACE_IO)
243 		return (inl(handle + offset));
244 	return (*(volatile u_int32_t *)(handle + offset));
245 }
246 
247 #ifdef __amd64__
248 static __inline uint64_t
bus_space_read_8(bus_space_tag_t tag,bus_space_handle_t handle,bus_size_t offset)249 bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle,
250 		 bus_size_t offset)
251 {
252 
253 	if (tag == X86_BUS_SPACE_IO) /* No 8 byte IO space access on x86 */
254 		return (BUS_SPACE_INVALID_DATA);
255 	return (*(volatile uint64_t *)(handle + offset));
256 }
257 #endif
258 
259 /*
260  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
261  * described by tag/handle/offset and copy into buffer provided.
262  */
263 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
264 					    bus_space_handle_t bsh,
265 					    bus_size_t offset, u_int8_t *addr,
266 					    size_t count);
267 
268 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
269 					    bus_space_handle_t bsh,
270 					    bus_size_t offset, u_int16_t *addr,
271 					    size_t count);
272 
273 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
274 					    bus_space_handle_t bsh,
275 					    bus_size_t offset, u_int32_t *addr,
276 					    size_t count);
277 
278 static __inline void
bus_space_read_multi_1(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int8_t * addr,size_t count)279 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
280 		       bus_size_t offset, u_int8_t *addr, size_t count)
281 {
282 
283 	if (tag == X86_BUS_SPACE_IO)
284 		insb(bsh + offset, addr, count);
285 	else {
286 #ifdef __GNUCLIKE_ASM
287 		__asm __volatile("				\n\
288 		1:	movb (%2),%%al				\n\
289 			stosb					\n\
290 			loop 1b"				:
291 		    "=D" (addr), "=c" (count)			:
292 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
293 		    "%eax", "memory");
294 #endif
295 	}
296 }
297 
298 static __inline void
bus_space_read_multi_2(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int16_t * addr,size_t count)299 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
300 		       bus_size_t offset, u_int16_t *addr, size_t count)
301 {
302 
303 	if (tag == X86_BUS_SPACE_IO)
304 		insw(bsh + offset, addr, count);
305 	else {
306 #ifdef __GNUCLIKE_ASM
307 		__asm __volatile("				\n\
308 		1:	movw (%2),%%ax				\n\
309 			stosw					\n\
310 			loop 1b"				:
311 		    "=D" (addr), "=c" (count)			:
312 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
313 		    "%eax", "memory");
314 #endif
315 	}
316 }
317 
318 static __inline void
bus_space_read_multi_4(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int32_t * addr,size_t count)319 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
320 		       bus_size_t offset, u_int32_t *addr, size_t count)
321 {
322 
323 	if (tag == X86_BUS_SPACE_IO)
324 		insl(bsh + offset, addr, count);
325 	else {
326 #ifdef __GNUCLIKE_ASM
327 		__asm __volatile("				\n\
328 		1:	movl (%2),%%eax				\n\
329 			stosl					\n\
330 			loop 1b"				:
331 		    "=D" (addr), "=c" (count)			:
332 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
333 		    "%eax", "memory");
334 #endif
335 	}
336 }
337 
338 #if 0	/* Cause a link error for bus_space_read_multi_8 */
339 #define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
340 #endif
341 
342 /*
343  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
344  * described by tag/handle and starting at `offset' and copy into
345  * buffer provided.
346  */
347 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
348 					     bus_space_handle_t bsh,
349 					     bus_size_t offset, u_int8_t *addr,
350 					     size_t count);
351 
352 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
353 					     bus_space_handle_t bsh,
354 					     bus_size_t offset, u_int16_t *addr,
355 					     size_t count);
356 
357 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
358 					     bus_space_handle_t bsh,
359 					     bus_size_t offset, u_int32_t *addr,
360 					     size_t count);
361 
362 static __inline void
bus_space_read_region_1(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int8_t * addr,size_t count)363 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
364 			bus_size_t offset, u_int8_t *addr, size_t count)
365 {
366 
367 	if (tag == X86_BUS_SPACE_IO) {
368 		int _port_ = bsh + offset;
369 #ifdef __GNUCLIKE_ASM
370 		__asm __volatile("				\n\
371 		1:	inb %w2,%%al				\n\
372 			stosb					\n\
373 			incl %2					\n\
374 			loop 1b"				:
375 		    "=D" (addr), "=c" (count), "=d" (_port_)	:
376 		    "0" (addr), "1" (count), "2" (_port_)	:
377 		    "%eax", "memory", "cc");
378 #endif
379 	} else {
380 		bus_space_handle_t _port_ = bsh + offset;
381 #ifdef __GNUCLIKE_ASM
382 		__asm __volatile("				\n\
383 			repne					\n\
384 			movsb"					:
385 		    "=D" (addr), "=c" (count), "=S" (_port_)	:
386 		    "0" (addr), "1" (count), "2" (_port_)	:
387 		    "memory", "cc");
388 #endif
389 	}
390 }
391 
392 static __inline void
bus_space_read_region_2(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int16_t * addr,size_t count)393 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
394 			bus_size_t offset, u_int16_t *addr, size_t count)
395 {
396 
397 	if (tag == X86_BUS_SPACE_IO) {
398 		int _port_ = bsh + offset;
399 #ifdef __GNUCLIKE_ASM
400 		__asm __volatile("				\n\
401 		1:	inw %w2,%%ax				\n\
402 			stosw					\n\
403 			addl $2,%2				\n\
404 			loop 1b"				:
405 		    "=D" (addr), "=c" (count), "=d" (_port_)	:
406 		    "0" (addr), "1" (count), "2" (_port_)	:
407 		    "%eax", "memory", "cc");
408 #endif
409 	} else {
410 		bus_space_handle_t _port_ = bsh + offset;
411 #ifdef __GNUCLIKE_ASM
412 		__asm __volatile("				\n\
413 			repne					\n\
414 			movsw"					:
415 		    "=D" (addr), "=c" (count), "=S" (_port_)	:
416 		    "0" (addr), "1" (count), "2" (_port_)	:
417 		    "memory", "cc");
418 #endif
419 	}
420 }
421 
422 static __inline void
bus_space_read_region_4(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int32_t * addr,size_t count)423 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
424 			bus_size_t offset, u_int32_t *addr, size_t count)
425 {
426 
427 	if (tag == X86_BUS_SPACE_IO) {
428 		int _port_ = bsh + offset;
429 #ifdef __GNUCLIKE_ASM
430 		__asm __volatile("				\n\
431 		1:	inl %w2,%%eax				\n\
432 			stosl					\n\
433 			addl $4,%2				\n\
434 			loop 1b"				:
435 		    "=D" (addr), "=c" (count), "=d" (_port_)	:
436 		    "0" (addr), "1" (count), "2" (_port_)	:
437 		    "%eax", "memory", "cc");
438 #endif
439 	} else {
440 		bus_space_handle_t _port_ = bsh + offset;
441 #ifdef __GNUCLIKE_ASM
442 		__asm __volatile("				\n\
443 			repne					\n\
444 			movsl"					:
445 		    "=D" (addr), "=c" (count), "=S" (_port_)	:
446 		    "0" (addr), "1" (count), "2" (_port_)	:
447 		    "memory", "cc");
448 #endif
449 	}
450 }
451 
452 #if 0	/* Cause a link error for bus_space_read_region_8 */
453 #define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
454 #endif
455 
456 /*
457  * Write the 1, 2, 4, or 8 byte value `value' to bus space
458  * described by tag/handle/offset.
459  */
460 
461 static __inline void bus_space_write_1(bus_space_tag_t tag,
462 				       bus_space_handle_t bsh,
463 				       bus_size_t offset, u_int8_t value);
464 
465 static __inline void bus_space_write_2(bus_space_tag_t tag,
466 				       bus_space_handle_t bsh,
467 				       bus_size_t offset, u_int16_t value);
468 
469 static __inline void bus_space_write_4(bus_space_tag_t tag,
470 				       bus_space_handle_t bsh,
471 				       bus_size_t offset, u_int32_t value);
472 
473 #ifdef __amd64__
474 static __inline void bus_space_write_8(bus_space_tag_t tag,
475 				       bus_space_handle_t bsh,
476 				       bus_size_t offset, uint64_t value);
477 #endif
478 
479 static __inline void
bus_space_write_1(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int8_t value)480 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
481 		       bus_size_t offset, u_int8_t value)
482 {
483 
484 	if (tag == X86_BUS_SPACE_IO)
485 		outb(bsh + offset, value);
486 	else
487 		*(volatile u_int8_t *)(bsh + offset) = value;
488 }
489 
490 static __inline void
bus_space_write_2(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int16_t value)491 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
492 		       bus_size_t offset, u_int16_t value)
493 {
494 
495 	if (tag == X86_BUS_SPACE_IO)
496 		outw(bsh + offset, value);
497 	else
498 		*(volatile u_int16_t *)(bsh + offset) = value;
499 }
500 
501 static __inline void
bus_space_write_4(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int32_t value)502 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
503 		       bus_size_t offset, u_int32_t value)
504 {
505 
506 	if (tag == X86_BUS_SPACE_IO)
507 		outl(bsh + offset, value);
508 	else
509 		*(volatile u_int32_t *)(bsh + offset) = value;
510 }
511 
512 #ifdef __amd64__
513 static __inline void
bus_space_write_8(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,uint64_t value)514 bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t bsh,
515 		  bus_size_t offset, uint64_t value)
516 {
517 
518 	if (tag == X86_BUS_SPACE_IO) /* No 8 byte IO space access on x86 */
519 		return;
520 	else
521 		*(volatile uint64_t *)(bsh + offset) = value;
522 }
523 #endif
524 
525 /*
526  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
527  * provided to bus space described by tag/handle/offset.
528  */
529 
530 static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
531 					     bus_space_handle_t bsh,
532 					     bus_size_t offset,
533 					     const u_int8_t *addr,
534 					     size_t count);
535 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
536 					     bus_space_handle_t bsh,
537 					     bus_size_t offset,
538 					     const u_int16_t *addr,
539 					     size_t count);
540 
541 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
542 					     bus_space_handle_t bsh,
543 					     bus_size_t offset,
544 					     const u_int32_t *addr,
545 					     size_t count);
546 
547 static __inline void
bus_space_write_multi_1(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,const u_int8_t * addr,size_t count)548 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
549 			bus_size_t offset, const u_int8_t *addr, size_t count)
550 {
551 
552 	if (tag == X86_BUS_SPACE_IO)
553 		outsb(bsh + offset, addr, count);
554 	else {
555 #ifdef __GNUCLIKE_ASM
556 		__asm __volatile("				\n\
557 		1:	lodsb					\n\
558 			movb %%al,(%2)				\n\
559 			loop 1b"				:
560 		    "=S" (addr), "=c" (count)			:
561 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
562 		    "%eax", "memory", "cc");
563 #endif
564 	}
565 }
566 
567 static __inline void
bus_space_write_multi_2(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,const u_int16_t * addr,size_t count)568 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
569 			bus_size_t offset, const u_int16_t *addr, size_t count)
570 {
571 
572 	if (tag == X86_BUS_SPACE_IO)
573 		outsw(bsh + offset, addr, count);
574 	else {
575 #ifdef __GNUCLIKE_ASM
576 		__asm __volatile("				\n\
577 		1:	lodsw					\n\
578 			movw %%ax,(%2)				\n\
579 			loop 1b"				:
580 		    "=S" (addr), "=c" (count)			:
581 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
582 		    "%eax", "memory", "cc");
583 #endif
584 	}
585 }
586 
587 static __inline void
bus_space_write_multi_4(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,const u_int32_t * addr,size_t count)588 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
589 			bus_size_t offset, const u_int32_t *addr, size_t count)
590 {
591 
592 	if (tag == X86_BUS_SPACE_IO)
593 		outsl(bsh + offset, addr, count);
594 	else {
595 #ifdef __GNUCLIKE_ASM
596 		__asm __volatile("				\n\
597 		1:	lodsl					\n\
598 			movl %%eax,(%2)				\n\
599 			loop 1b"				:
600 		    "=S" (addr), "=c" (count)			:
601 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
602 		    "%eax", "memory", "cc");
603 #endif
604 	}
605 }
606 
607 #if 0	/* Cause a link error for bus_space_write_multi_8 */
608 #define	bus_space_write_multi_8(t, h, o, a, c)				\
609 			!!! bus_space_write_multi_8 unimplemented !!!
610 #endif
611 
612 /*
613  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
614  * to bus space described by tag/handle starting at `offset'.
615  */
616 
617 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
618 					      bus_space_handle_t bsh,
619 					      bus_size_t offset,
620 					      const u_int8_t *addr,
621 					      size_t count);
622 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
623 					      bus_space_handle_t bsh,
624 					      bus_size_t offset,
625 					      const u_int16_t *addr,
626 					      size_t count);
627 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
628 					      bus_space_handle_t bsh,
629 					      bus_size_t offset,
630 					      const u_int32_t *addr,
631 					      size_t count);
632 
633 static __inline void
bus_space_write_region_1(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,const u_int8_t * addr,size_t count)634 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
635 			 bus_size_t offset, const u_int8_t *addr, size_t count)
636 {
637 
638 	if (tag == X86_BUS_SPACE_IO) {
639 		int _port_ = bsh + offset;
640 #ifdef __GNUCLIKE_ASM
641 		__asm __volatile("				\n\
642 		1:	lodsb					\n\
643 			outb %%al,%w0				\n\
644 			incl %0					\n\
645 			loop 1b"				:
646 		    "=d" (_port_), "=S" (addr), "=c" (count)	:
647 		    "0" (_port_), "1" (addr), "2" (count)	:
648 		    "%eax", "memory", "cc");
649 #endif
650 	} else {
651 		bus_space_handle_t _port_ = bsh + offset;
652 #ifdef __GNUCLIKE_ASM
653 		__asm __volatile("				\n\
654 			repne					\n\
655 			movsb"					:
656 		    "=D" (_port_), "=S" (addr), "=c" (count)	:
657 		    "0" (_port_), "1" (addr), "2" (count)	:
658 		    "memory", "cc");
659 #endif
660 	}
661 }
662 
663 static __inline void
bus_space_write_region_2(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,const u_int16_t * addr,size_t count)664 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
665 			 bus_size_t offset, const u_int16_t *addr, size_t count)
666 {
667 
668 	if (tag == X86_BUS_SPACE_IO) {
669 		int _port_ = bsh + offset;
670 #ifdef __GNUCLIKE_ASM
671 		__asm __volatile("				\n\
672 		1:	lodsw					\n\
673 			outw %%ax,%w0				\n\
674 			addl $2,%0				\n\
675 			loop 1b"				:
676 		    "=d" (_port_), "=S" (addr), "=c" (count)	:
677 		    "0" (_port_), "1" (addr), "2" (count)	:
678 		    "%eax", "memory", "cc");
679 #endif
680 	} else {
681 		bus_space_handle_t _port_ = bsh + offset;
682 #ifdef __GNUCLIKE_ASM
683 		__asm __volatile("				\n\
684 			repne					\n\
685 			movsw"					:
686 		    "=D" (_port_), "=S" (addr), "=c" (count)	:
687 		    "0" (_port_), "1" (addr), "2" (count)	:
688 		    "memory", "cc");
689 #endif
690 	}
691 }
692 
693 static __inline void
bus_space_write_region_4(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,const u_int32_t * addr,size_t count)694 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
695 			 bus_size_t offset, const u_int32_t *addr, size_t count)
696 {
697 
698 	if (tag == X86_BUS_SPACE_IO) {
699 		int _port_ = bsh + offset;
700 #ifdef __GNUCLIKE_ASM
701 		__asm __volatile("				\n\
702 		1:	lodsl					\n\
703 			outl %%eax,%w0				\n\
704 			addl $4,%0				\n\
705 			loop 1b"				:
706 		    "=d" (_port_), "=S" (addr), "=c" (count)	:
707 		    "0" (_port_), "1" (addr), "2" (count)	:
708 		    "%eax", "memory", "cc");
709 #endif
710 	} else {
711 		bus_space_handle_t _port_ = bsh + offset;
712 #ifdef __GNUCLIKE_ASM
713 		__asm __volatile("				\n\
714 			repne					\n\
715 			movsl"					:
716 		    "=D" (_port_), "=S" (addr), "=c" (count)	:
717 		    "0" (_port_), "1" (addr), "2" (count)	:
718 		    "memory", "cc");
719 #endif
720 	}
721 }
722 
723 #if 0	/* Cause a link error for bus_space_write_region_8 */
724 #define	bus_space_write_region_8					\
725 			!!! bus_space_write_region_8 unimplemented !!!
726 #endif
727 
728 /*
729  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
730  * by tag/handle/offset `count' times.
731  */
732 
733 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
734 					   bus_space_handle_t bsh,
735 					   bus_size_t offset,
736 					   u_int8_t value, size_t count);
737 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
738 					   bus_space_handle_t bsh,
739 					   bus_size_t offset,
740 					   u_int16_t value, size_t count);
741 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
742 					   bus_space_handle_t bsh,
743 					   bus_size_t offset,
744 					   u_int32_t value, size_t count);
745 
746 static __inline void
bus_space_set_multi_1(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int8_t value,size_t count)747 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
748 		      bus_size_t offset, u_int8_t value, size_t count)
749 {
750 	bus_space_handle_t addr = bsh + offset;
751 
752 	if (tag == X86_BUS_SPACE_IO)
753 		while (count--)
754 			outb(addr, value);
755 	else
756 		while (count--)
757 			*(volatile u_int8_t *)(addr) = value;
758 }
759 
760 static __inline void
bus_space_set_multi_2(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int16_t value,size_t count)761 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
762 		     bus_size_t offset, u_int16_t value, size_t count)
763 {
764 	bus_space_handle_t addr = bsh + offset;
765 
766 	if (tag == X86_BUS_SPACE_IO)
767 		while (count--)
768 			outw(addr, value);
769 	else
770 		while (count--)
771 			*(volatile u_int16_t *)(addr) = value;
772 }
773 
774 static __inline void
bus_space_set_multi_4(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int32_t value,size_t count)775 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
776 		      bus_size_t offset, u_int32_t value, size_t count)
777 {
778 	bus_space_handle_t addr = bsh + offset;
779 
780 	if (tag == X86_BUS_SPACE_IO)
781 		while (count--)
782 			outl(addr, value);
783 	else
784 		while (count--)
785 			*(volatile u_int32_t *)(addr) = value;
786 }
787 
788 #if 0	/* Cause a link error for bus_space_set_multi_8 */
789 #define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
790 #endif
791 
792 /*
793  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
794  * by tag/handle starting at `offset'.
795  */
796 
797 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
798 					    bus_space_handle_t bsh,
799 					    bus_size_t offset, u_int8_t value,
800 					    size_t count);
801 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
802 					    bus_space_handle_t bsh,
803 					    bus_size_t offset, u_int16_t value,
804 					    size_t count);
805 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
806 					    bus_space_handle_t bsh,
807 					    bus_size_t offset, u_int32_t value,
808 					    size_t count);
809 
810 static __inline void
bus_space_set_region_1(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int8_t value,size_t count)811 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
812 		       bus_size_t offset, u_int8_t value, size_t count)
813 {
814 	bus_space_handle_t addr = bsh + offset;
815 
816 	if (tag == X86_BUS_SPACE_IO)
817 		for (; count != 0; count--, addr++)
818 			outb(addr, value);
819 	else
820 		for (; count != 0; count--, addr++)
821 			*(volatile u_int8_t *)(addr) = value;
822 }
823 
824 static __inline void
bus_space_set_region_2(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int16_t value,size_t count)825 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
826 		       bus_size_t offset, u_int16_t value, size_t count)
827 {
828 	bus_space_handle_t addr = bsh + offset;
829 
830 	if (tag == X86_BUS_SPACE_IO)
831 		for (; count != 0; count--, addr += 2)
832 			outw(addr, value);
833 	else
834 		for (; count != 0; count--, addr += 2)
835 			*(volatile u_int16_t *)(addr) = value;
836 }
837 
838 static __inline void
bus_space_set_region_4(bus_space_tag_t tag,bus_space_handle_t bsh,bus_size_t offset,u_int32_t value,size_t count)839 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
840 		       bus_size_t offset, u_int32_t value, size_t count)
841 {
842 	bus_space_handle_t addr = bsh + offset;
843 
844 	if (tag == X86_BUS_SPACE_IO)
845 		for (; count != 0; count--, addr += 4)
846 			outl(addr, value);
847 	else
848 		for (; count != 0; count--, addr += 4)
849 			*(volatile u_int32_t *)(addr) = value;
850 }
851 
852 #if 0	/* Cause a link error for bus_space_set_region_8 */
853 #define	bus_space_set_region_8	!!! bus_space_set_region_8 unimplemented !!!
854 #endif
855 
856 /*
857  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
858  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
859  */
860 
861 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
862 					     bus_space_handle_t bsh1,
863 					     bus_size_t off1,
864 					     bus_space_handle_t bsh2,
865 					     bus_size_t off2, size_t count);
866 
867 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
868 					     bus_space_handle_t bsh1,
869 					     bus_size_t off1,
870 					     bus_space_handle_t bsh2,
871 					     bus_size_t off2, size_t count);
872 
873 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
874 					     bus_space_handle_t bsh1,
875 					     bus_size_t off1,
876 					     bus_space_handle_t bsh2,
877 					     bus_size_t off2, size_t count);
878 
879 static __inline void
bus_space_copy_region_1(bus_space_tag_t tag,bus_space_handle_t bsh1,bus_size_t off1,bus_space_handle_t bsh2,bus_size_t off2,size_t count)880 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
881 			bus_size_t off1, bus_space_handle_t bsh2,
882 			bus_size_t off2, size_t count)
883 {
884 	bus_space_handle_t addr1 = bsh1 + off1;
885 	bus_space_handle_t addr2 = bsh2 + off2;
886 
887 	if (tag == X86_BUS_SPACE_IO) {
888 		if (addr1 >= addr2) {
889 			/* src after dest: copy forward */
890 			for (; count != 0; count--, addr1++, addr2++)
891 				outb(addr2, inb(addr1));
892 		} else {
893 			/* dest after src: copy backwards */
894 			for (addr1 += (count - 1), addr2 += (count - 1);
895 			    count != 0; count--, addr1--, addr2--)
896 				outb(addr2, inb(addr1));
897 		}
898 	} else {
899 		if (addr1 >= addr2) {
900 			/* src after dest: copy forward */
901 			for (; count != 0; count--, addr1++, addr2++)
902 				*(volatile u_int8_t *)(addr2) =
903 				    *(volatile u_int8_t *)(addr1);
904 		} else {
905 			/* dest after src: copy backwards */
906 			for (addr1 += (count - 1), addr2 += (count - 1);
907 			    count != 0; count--, addr1--, addr2--)
908 				*(volatile u_int8_t *)(addr2) =
909 				    *(volatile u_int8_t *)(addr1);
910 		}
911 	}
912 }
913 
914 static __inline void
bus_space_copy_region_2(bus_space_tag_t tag,bus_space_handle_t bsh1,bus_size_t off1,bus_space_handle_t bsh2,bus_size_t off2,size_t count)915 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
916 			bus_size_t off1, bus_space_handle_t bsh2,
917 			bus_size_t off2, size_t count)
918 {
919 	bus_space_handle_t addr1 = bsh1 + off1;
920 	bus_space_handle_t addr2 = bsh2 + off2;
921 
922 	if (tag == X86_BUS_SPACE_IO) {
923 		if (addr1 >= addr2) {
924 			/* src after dest: copy forward */
925 			for (; count != 0; count--, addr1 += 2, addr2 += 2)
926 				outw(addr2, inw(addr1));
927 		} else {
928 			/* dest after src: copy backwards */
929 			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
930 			    count != 0; count--, addr1 -= 2, addr2 -= 2)
931 				outw(addr2, inw(addr1));
932 		}
933 	} else {
934 		if (addr1 >= addr2) {
935 			/* src after dest: copy forward */
936 			for (; count != 0; count--, addr1 += 2, addr2 += 2)
937 				*(volatile u_int16_t *)(addr2) =
938 				    *(volatile u_int16_t *)(addr1);
939 		} else {
940 			/* dest after src: copy backwards */
941 			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
942 			    count != 0; count--, addr1 -= 2, addr2 -= 2)
943 				*(volatile u_int16_t *)(addr2) =
944 				    *(volatile u_int16_t *)(addr1);
945 		}
946 	}
947 }
948 
949 static __inline void
bus_space_copy_region_4(bus_space_tag_t tag,bus_space_handle_t bsh1,bus_size_t off1,bus_space_handle_t bsh2,bus_size_t off2,size_t count)950 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
951 			bus_size_t off1, bus_space_handle_t bsh2,
952 			bus_size_t off2, size_t count)
953 {
954 	bus_space_handle_t addr1 = bsh1 + off1;
955 	bus_space_handle_t addr2 = bsh2 + off2;
956 
957 	if (tag == X86_BUS_SPACE_IO) {
958 		if (addr1 >= addr2) {
959 			/* src after dest: copy forward */
960 			for (; count != 0; count--, addr1 += 4, addr2 += 4)
961 				outl(addr2, inl(addr1));
962 		} else {
963 			/* dest after src: copy backwards */
964 			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
965 			    count != 0; count--, addr1 -= 4, addr2 -= 4)
966 				outl(addr2, inl(addr1));
967 		}
968 	} else {
969 		if (addr1 >= addr2) {
970 			/* src after dest: copy forward */
971 			for (; count != 0; count--, addr1 += 4, addr2 += 4)
972 				*(volatile u_int32_t *)(addr2) =
973 				    *(volatile u_int32_t *)(addr1);
974 		} else {
975 			/* dest after src: copy backwards */
976 			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
977 			    count != 0; count--, addr1 -= 4, addr2 -= 4)
978 				*(volatile u_int32_t *)(addr2) =
979 				    *(volatile u_int32_t *)(addr1);
980 		}
981 	}
982 }
983 
984 #if 0	/* Cause a link error for bus_space_copy_8 */
985 #define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
986 #endif
987 
988 /*
989  * Bus read/write barrier methods.
990  *
991  *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
992  *			       bus_size_t offset, bus_size_t len, int flags);
993  *
994  *
995  * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
996  * prevent reordering by the compiler; all Intel x86 processors currently
997  * retire operations outside the CPU in program order.
998  */
999 static __inline void
bus_space_barrier(bus_space_tag_t tag __unused,bus_space_handle_t bsh __unused,bus_size_t offset __unused,bus_size_t len __unused,int flags)1000 bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
1001 		  bus_size_t offset __unused, bus_size_t len __unused, int flags)
1002 {
1003 #ifdef __GNUCLIKE_ASM
1004 	if (flags & BUS_SPACE_BARRIER_READ)
1005 #ifdef __amd64__
1006 		__asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
1007 #else
1008 		__asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
1009 #endif
1010 	else
1011 		__compiler_membar();
1012 #endif
1013 }
1014 
1015 #ifdef BUS_SPACE_NO_LEGACY
1016 #undef inb
1017 #undef outb
1018 #define inb(a) compiler_error
1019 #define inw(a) compiler_error
1020 #define inl(a) compiler_error
1021 #define outb(a, b) compiler_error
1022 #define outw(a, b) compiler_error
1023 #define outl(a, b) compiler_error
1024 #endif
1025 
1026 /*
1027  * Stream accesses are the same as normal accesses on x86; there are no
1028  * supported bus systems with an endianess different from the host one.
1029  */
1030 #define	bus_space_read_stream_1(t, h, o)	bus_space_read_1((t), (h), (o))
1031 #define	bus_space_read_stream_2(t, h, o)	bus_space_read_2((t), (h), (o))
1032 #define	bus_space_read_stream_4(t, h, o)	bus_space_read_4((t), (h), (o))
1033 
1034 #define	bus_space_read_multi_stream_1(t, h, o, a, c) \
1035 	bus_space_read_multi_1((t), (h), (o), (a), (c))
1036 #define	bus_space_read_multi_stream_2(t, h, o, a, c) \
1037 	bus_space_read_multi_2((t), (h), (o), (a), (c))
1038 #define	bus_space_read_multi_stream_4(t, h, o, a, c) \
1039 	bus_space_read_multi_4((t), (h), (o), (a), (c))
1040 
1041 #define	bus_space_write_stream_1(t, h, o, v) \
1042 	bus_space_write_1((t), (h), (o), (v))
1043 #define	bus_space_write_stream_2(t, h, o, v) \
1044 	bus_space_write_2((t), (h), (o), (v))
1045 #define	bus_space_write_stream_4(t, h, o, v) \
1046 	bus_space_write_4((t), (h), (o), (v))
1047 
1048 #define	bus_space_write_multi_stream_1(t, h, o, a, c) \
1049 	bus_space_write_multi_1((t), (h), (o), (a), (c))
1050 #define	bus_space_write_multi_stream_2(t, h, o, a, c) \
1051 	bus_space_write_multi_2((t), (h), (o), (a), (c))
1052 #define	bus_space_write_multi_stream_4(t, h, o, a, c) \
1053 	bus_space_write_multi_4((t), (h), (o), (a), (c))
1054 
1055 #define	bus_space_set_multi_stream_1(t, h, o, v, c) \
1056 	bus_space_set_multi_1((t), (h), (o), (v), (c))
1057 #define	bus_space_set_multi_stream_2(t, h, o, v, c) \
1058 	bus_space_set_multi_2((t), (h), (o), (v), (c))
1059 #define	bus_space_set_multi_stream_4(t, h, o, v, c) \
1060 	bus_space_set_multi_4((t), (h), (o), (v), (c))
1061 
1062 #define	bus_space_read_region_stream_1(t, h, o, a, c) \
1063 	bus_space_read_region_1((t), (h), (o), (a), (c))
1064 #define	bus_space_read_region_stream_2(t, h, o, a, c) \
1065 	bus_space_read_region_2((t), (h), (o), (a), (c))
1066 #define	bus_space_read_region_stream_4(t, h, o, a, c) \
1067 	bus_space_read_region_4((t), (h), (o), (a), (c))
1068 
1069 #define	bus_space_write_region_stream_1(t, h, o, a, c) \
1070 	bus_space_write_region_1((t), (h), (o), (a), (c))
1071 #define	bus_space_write_region_stream_2(t, h, o, a, c) \
1072 	bus_space_write_region_2((t), (h), (o), (a), (c))
1073 #define	bus_space_write_region_stream_4(t, h, o, a, c) \
1074 	bus_space_write_region_4((t), (h), (o), (a), (c))
1075 
1076 #define	bus_space_set_region_stream_1(t, h, o, v, c) \
1077 	bus_space_set_region_1((t), (h), (o), (v), (c))
1078 #define	bus_space_set_region_stream_2(t, h, o, v, c) \
1079 	bus_space_set_region_2((t), (h), (o), (v), (c))
1080 #define	bus_space_set_region_stream_4(t, h, o, v, c) \
1081 	bus_space_set_region_4((t), (h), (o), (v), (c))
1082 
1083 #define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
1084 	bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
1085 #define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
1086 	bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
1087 #define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
1088 	bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
1089 
1090 #define BUS_PEEK_FUNC(width, type)					\
1091 	static inline int						\
1092 	bus_space_peek_##width(bus_space_tag_t tag,			\
1093 	    bus_space_handle_t hnd, bus_size_t offset, type *value)	\
1094 	{								\
1095 		type tmp;						\
1096 		tmp = bus_space_read_##width(tag, hnd, offset);		\
1097 		*value = (type)tmp;					\
1098 		return (0);						\
1099 	}
1100 BUS_PEEK_FUNC(1, uint8_t)
1101 BUS_PEEK_FUNC(2, uint16_t)
1102 BUS_PEEK_FUNC(4, uint32_t)
1103 #ifdef __amd64__
1104 BUS_PEEK_FUNC(8, uint64_t)
1105 #endif
1106 
1107 #define BUS_POKE_FUNC(width, type)					\
1108 	static inline int						\
1109 	bus_space_poke_##width(bus_space_tag_t tag,			\
1110 	    bus_space_handle_t hnd, bus_size_t offset, type value)	\
1111 	{								\
1112 		bus_space_write_##width(tag, hnd, offset, value);	\
1113 		return (0); 						\
1114 	}
1115 BUS_POKE_FUNC(1, uint8_t)
1116 BUS_POKE_FUNC(2, uint16_t)
1117 BUS_POKE_FUNC(4, uint32_t)
1118 #ifdef __amd64__
1119 BUS_POKE_FUNC(8, uint64_t)
1120 #endif
1121 
1122 #endif /* !SAN_NEEDS_INTERCEPTORS && SAN_RUNTIME */
1123 
1124 #endif /* !_MACHINE_BUS_H_ */
1125