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