bus.h revision 144604
1/*-
2 * Copyright (c) KATO Takenori, 1999.
3 *
4 * All rights reserved.  Unpublished rights reserved under the copyright
5 * laws of Japan.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer as
13 *    the first lines of this file unmodified.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 *    derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $FreeBSD: head/sys/i386/include/bus.h 144604 2005-04-03 17:47:03Z imp $
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 * 3. All advertising materials mentioning features or use of this software
53 *    must display the following acknowledgement:
54 *	This product includes software developed by the NetBSD
55 *	Foundation, Inc. and its contributors.
56 * 4. Neither the name of The NetBSD Foundation nor the names of its
57 *    contributors may be used to endorse or promote products derived
58 *    from this software without specific prior written permission.
59 *
60 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
61 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
62 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
64 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
65 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
66 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
67 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
68 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
69 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
70 * POSSIBILITY OF SUCH DAMAGE.
71 */
72
73/*-
74 * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
75 * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
76 *
77 * Redistribution and use in source and binary forms, with or without
78 * modification, are permitted provided that the following conditions
79 * are met:
80 * 1. Redistributions of source code must retain the above copyright
81 *    notice, this list of conditions and the following disclaimer.
82 * 2. Redistributions in binary form must reproduce the above copyright
83 *    notice, this list of conditions and the following disclaimer in the
84 *    documentation and/or other materials provided with the distribution.
85 * 3. All advertising materials mentioning features or use of this software
86 *    must display the following acknowledgement:
87 *      This product includes software developed by Christopher G. Demetriou
88 *	for the NetBSD Project.
89 * 4. The name of the author may not be used to endorse or promote products
90 *    derived from this software without specific prior written permission
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
93 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
94 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
95 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
96 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
99 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
101 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102 */
103
104#ifndef _I386_BUS_H_
105#define _I386_BUS_H_
106
107#include <machine/cpufunc.h>
108
109/*
110 * To remain compatible with NetBSD's interface, default to both memio and
111 * pio when neither of them is defined.
112 */
113#if !defined(_I386_BUS_PIO_H_) && !defined(_I386_BUS_MEMIO_H_)
114#define _I386_BUS_PIO_H_
115#define _I386_BUS_MEMIO_H_
116#endif
117
118/*
119 * Values for the i386 bus space tag, not to be used directly by MI code.
120 */
121#define	I386_BUS_SPACE_IO	0	/* space is i/o space */
122#define I386_BUS_SPACE_MEM	1	/* space is mem space */
123
124/*
125 * Bus address and size types
126 */
127#ifdef PAE
128typedef uint64_t bus_addr_t;
129#else
130typedef uint32_t bus_addr_t;
131#endif
132typedef uint32_t bus_size_t;
133
134#define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
135#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
136#define BUS_SPACE_MAXSIZE	0xFFFFFFFF
137#define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
138#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
139#ifdef PAE
140#define BUS_SPACE_MAXADDR	0xFFFFFFFFFFFFFFFFULL
141#else
142#define BUS_SPACE_MAXADDR	0xFFFFFFFF
143#endif
144
145#define BUS_SPACE_UNRESTRICTED	(~0)
146
147/*
148 * Access methods for bus resources and address space.
149 */
150typedef	int bus_space_tag_t;
151typedef	u_int bus_space_handle_t;
152
153/*
154 * Map a region of device bus space into CPU virtual address space.
155 */
156
157static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
158				  bus_size_t size, int flags,
159				  bus_space_handle_t *bshp);
160
161static __inline int
162bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
163	      bus_size_t size __unused, int flags __unused,
164	      bus_space_handle_t *bshp)
165{
166
167	*bshp = addr;
168	return (0);
169}
170
171/*
172 * Unmap a region of device bus space.
173 */
174
175static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
176				     bus_size_t size);
177
178static __inline void
179bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
180		bus_size_t size __unused)
181{
182}
183
184/*
185 * Get a new handle for a subregion of an already-mapped area of bus space.
186 */
187
188static __inline int bus_space_subregion(bus_space_tag_t t,
189					bus_space_handle_t bsh,
190					bus_size_t offset, bus_size_t size,
191					bus_space_handle_t *nbshp);
192
193static __inline int
194bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
195		    bus_size_t offset, bus_size_t size __unused,
196		    bus_space_handle_t *nbshp)
197{
198
199	*nbshp = bsh + offset;
200	return (0);
201}
202
203/*
204 * Allocate a region of memory that is accessible to devices in bus space.
205 */
206
207int	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
208			bus_addr_t rend, bus_size_t size, bus_size_t align,
209			bus_size_t boundary, int flags, bus_addr_t *addrp,
210			bus_space_handle_t *bshp);
211
212/*
213 * Free a region of bus space accessible memory.
214 */
215
216static __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
217				    bus_size_t size);
218
219static __inline void
220bus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
221	       bus_size_t size __unused)
222{
223}
224
225
226#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_)
227
228/*
229 * Read a 1, 2, 4, or 8 byte quantity from bus space
230 * described by tag/handle/offset.
231 */
232static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
233					  bus_space_handle_t handle,
234					  bus_size_t offset);
235
236static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
237					   bus_space_handle_t handle,
238					   bus_size_t offset);
239
240static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
241					   bus_space_handle_t handle,
242					   bus_size_t offset);
243
244static __inline u_int8_t
245bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
246		 bus_size_t offset)
247{
248#if defined (_I386_BUS_PIO_H_)
249#if defined (_I386_BUS_MEMIO_H_)
250	if (tag == I386_BUS_SPACE_IO)
251#endif
252		return (inb(handle + offset));
253#endif
254#if defined (_I386_BUS_MEMIO_H_)
255	return (*(volatile u_int8_t *)(handle + offset));
256#endif
257}
258
259static __inline u_int16_t
260bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
261		 bus_size_t offset)
262{
263#if defined(_I386_BUS_PIO_H_)
264#if defined(_I386_BUS_MEMIO_H_)
265	if (tag == I386_BUS_SPACE_IO)
266#endif
267		return (inw(handle + offset));
268#endif
269#if defined(_I386_BUS_MEMIO_H_)
270	return (*(volatile u_int16_t *)(handle + offset));
271#endif
272}
273
274static __inline u_int32_t
275bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
276		 bus_size_t offset)
277{
278#if defined(_I386_BUS_PIO_H_)
279#if defined(_I386_BUS_MEMIO_H_)
280	if (tag == I386_BUS_SPACE_IO)
281#endif
282		return (inl(handle + offset));
283#endif
284#if defined(_I386_BUS_MEMIO_H_)
285	return (*(volatile u_int32_t *)(handle + offset));
286#endif
287}
288
289#if 0	/* Cause a link error for bus_space_read_8 */
290#define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
291#endif
292
293/*
294 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
295 * described by tag/handle/offset and copy into buffer provided.
296 */
297static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
298					    bus_space_handle_t bsh,
299					    bus_size_t offset, u_int8_t *addr,
300					    size_t count);
301
302static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
303					    bus_space_handle_t bsh,
304					    bus_size_t offset, u_int16_t *addr,
305					    size_t count);
306
307static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
308					    bus_space_handle_t bsh,
309					    bus_size_t offset, u_int32_t *addr,
310					    size_t count);
311
312static __inline void
313bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
314		       bus_size_t offset, u_int8_t *addr, size_t count)
315{
316#if defined(_I386_BUS_PIO_H_)
317#if defined(_I386_BUS_MEMIO_H_)
318	if (tag == I386_BUS_SPACE_IO)
319#endif
320		insb(bsh + offset, addr, count);
321#endif
322#if defined(_I386_BUS_MEMIO_H_)
323#if defined(_I386_BUS_PIO_H_)
324	else
325#endif
326	{
327#ifdef __GNUCLIKE_ASM
328		__asm __volatile("				\n\
329			cld					\n\
330		1:	movb (%2),%%al				\n\
331			stosb					\n\
332			loop 1b"				:
333		    "=D" (addr), "=c" (count)			:
334		    "r" (bsh + offset), "0" (addr), "1" (count)	:
335		    "%eax", "memory");
336#else
337# ifndef lint
338#  error "no assembler code for your compiler"
339# endif
340#endif
341	}
342#endif
343}
344
345static __inline void
346bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
347		       bus_size_t offset, u_int16_t *addr, size_t count)
348{
349#if defined(_I386_BUS_PIO_H_)
350#if defined(_I386_BUS_MEMIO_H_)
351	if (tag == I386_BUS_SPACE_IO)
352#endif
353		insw(bsh + offset, addr, count);
354#endif
355#if defined(_I386_BUS_MEMIO_H_)
356#if defined(_I386_BUS_PIO_H_)
357	else
358#endif
359	{
360#ifdef __GNUCLIKE_ASM
361		__asm __volatile("				\n\
362			cld					\n\
363		1:	movw (%2),%%ax				\n\
364			stosw					\n\
365			loop 1b"				:
366		    "=D" (addr), "=c" (count)			:
367		    "r" (bsh + offset), "0" (addr), "1" (count)	:
368		    "%eax", "memory");
369#else
370# ifndef lint
371#  error "no assembler code for your compiler"
372# endif
373#endif
374	}
375#endif
376}
377
378static __inline void
379bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
380		       bus_size_t offset, u_int32_t *addr, size_t count)
381{
382#if defined(_I386_BUS_PIO_H_)
383#if defined(_I386_BUS_MEMIO_H_)
384	if (tag == I386_BUS_SPACE_IO)
385#endif
386		insl(bsh + offset, addr, count);
387#endif
388#if defined(_I386_BUS_MEMIO_H_)
389#if defined(_I386_BUS_PIO_H_)
390	else
391#endif
392	{
393#ifdef __GNUCLIKE_ASM
394		__asm __volatile("				\n\
395			cld					\n\
396		1:	movl (%2),%%eax				\n\
397			stosl					\n\
398			loop 1b"				:
399		    "=D" (addr), "=c" (count)			:
400		    "r" (bsh + offset), "0" (addr), "1" (count)	:
401		    "%eax", "memory");
402#else
403# ifndef lint
404#  error "no assembler code for your compiler"
405# endif
406#endif
407	}
408#endif
409}
410
411#if 0	/* Cause a link error for bus_space_read_multi_8 */
412#define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
413#endif
414
415/*
416 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
417 * described by tag/handle and starting at `offset' and copy into
418 * buffer provided.
419 */
420static __inline void bus_space_read_region_1(bus_space_tag_t tag,
421					     bus_space_handle_t bsh,
422					     bus_size_t offset, u_int8_t *addr,
423					     size_t count);
424
425static __inline void bus_space_read_region_2(bus_space_tag_t tag,
426					     bus_space_handle_t bsh,
427					     bus_size_t offset, u_int16_t *addr,
428					     size_t count);
429
430static __inline void bus_space_read_region_4(bus_space_tag_t tag,
431					     bus_space_handle_t bsh,
432					     bus_size_t offset, u_int32_t *addr,
433					     size_t count);
434
435
436static __inline void
437bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
438			bus_size_t offset, u_int8_t *addr, size_t count)
439{
440#if defined(_I386_BUS_PIO_H_)
441#if defined(_I386_BUS_MEMIO_H_)
442	if (tag == I386_BUS_SPACE_IO)
443#endif
444	{
445		int _port_ = bsh + offset;
446#ifdef __GNUCLIKE_ASM
447		__asm __volatile("				\n\
448			cld					\n\
449		1:	inb %w2,%%al				\n\
450			stosb					\n\
451			incl %2					\n\
452			loop 1b"				:
453		    "=D" (addr), "=c" (count), "=d" (_port_)	:
454		    "0" (addr), "1" (count), "2" (_port_)	:
455		    "%eax", "memory", "cc");
456#else
457# ifndef lint
458#  error "no assembler code for your compiler"
459# endif
460#endif
461	}
462#endif
463#if defined(_I386_BUS_MEMIO_H_)
464#if defined(_I386_BUS_PIO_H_)
465	else
466#endif
467	{
468		int _port_ = bsh + offset;
469#ifdef __GNUCLIKE_ASM
470		__asm __volatile("				\n\
471			cld					\n\
472			repne					\n\
473			movsb"					:
474		    "=D" (addr), "=c" (count), "=S" (_port_)	:
475		    "0" (addr), "1" (count), "2" (_port_)	:
476		    "memory", "cc");
477#else
478# ifndef lint
479#  error "no assembler code for your compiler"
480# endif
481#endif
482	}
483#endif
484}
485
486static __inline void
487bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
488			bus_size_t offset, u_int16_t *addr, size_t count)
489{
490#if defined(_I386_BUS_PIO_H_)
491#if defined(_I386_BUS_MEMIO_H_)
492	if (tag == I386_BUS_SPACE_IO)
493#endif
494	{
495		int _port_ = bsh + offset;
496#ifdef __GNUCLIKE_ASM
497		__asm __volatile("				\n\
498			cld					\n\
499		1:	inw %w2,%%ax				\n\
500			stosw					\n\
501			addl $2,%2				\n\
502			loop 1b"				:
503		    "=D" (addr), "=c" (count), "=d" (_port_)	:
504		    "0" (addr), "1" (count), "2" (_port_)	:
505		    "%eax", "memory", "cc");
506#else
507# ifndef lint
508#  error "no assembler code for your compiler"
509# endif
510#endif
511	}
512#endif
513#if defined(_I386_BUS_MEMIO_H_)
514#if defined(_I386_BUS_PIO_H_)
515	else
516#endif
517	{
518		int _port_ = bsh + offset;
519#ifdef __GNUCLIKE_ASM
520		__asm __volatile("				\n\
521			cld					\n\
522			repne					\n\
523			movsw"					:
524		    "=D" (addr), "=c" (count), "=S" (_port_)	:
525		    "0" (addr), "1" (count), "2" (_port_)	:
526		    "memory", "cc");
527#else
528# ifndef lint
529#  error "no assembler code for your compiler"
530# endif
531#endif
532	}
533#endif
534}
535
536static __inline void
537bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
538			bus_size_t offset, u_int32_t *addr, size_t count)
539{
540#if defined(_I386_BUS_PIO_H_)
541#if defined(_I386_BUS_MEMIO_H_)
542	if (tag == I386_BUS_SPACE_IO)
543#endif
544	{
545		int _port_ = bsh + offset;
546#ifdef __GNUCLIKE_ASM
547		__asm __volatile("				\n\
548			cld					\n\
549		1:	inl %w2,%%eax				\n\
550			stosl					\n\
551			addl $4,%2				\n\
552			loop 1b"				:
553		    "=D" (addr), "=c" (count), "=d" (_port_)	:
554		    "0" (addr), "1" (count), "2" (_port_)	:
555		    "%eax", "memory", "cc");
556#else
557# ifndef lint
558#  error "no assembler code for your compiler"
559# endif
560#endif
561	}
562#endif
563#if defined(_I386_BUS_MEMIO_H_)
564#if defined(_I386_BUS_PIO_H_)
565	else
566#endif
567	{
568		int _port_ = bsh + offset;
569#ifdef __GNUCLIKE_ASM
570		__asm __volatile("				\n\
571			cld					\n\
572			repne					\n\
573			movsl"					:
574		    "=D" (addr), "=c" (count), "=S" (_port_)	:
575		    "0" (addr), "1" (count), "2" (_port_)	:
576		    "memory", "cc");
577#else
578# ifndef lint
579#  error "no assembler code for your compiler"
580# endif
581#endif
582	}
583#endif
584}
585
586#if 0	/* Cause a link error for bus_space_read_region_8 */
587#define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
588#endif
589
590/*
591 * Write the 1, 2, 4, or 8 byte value `value' to bus space
592 * described by tag/handle/offset.
593 */
594
595static __inline void bus_space_write_1(bus_space_tag_t tag,
596				       bus_space_handle_t bsh,
597				       bus_size_t offset, u_int8_t value);
598
599static __inline void bus_space_write_2(bus_space_tag_t tag,
600				       bus_space_handle_t bsh,
601				       bus_size_t offset, u_int16_t value);
602
603static __inline void bus_space_write_4(bus_space_tag_t tag,
604				       bus_space_handle_t bsh,
605				       bus_size_t offset, u_int32_t value);
606
607static __inline void
608bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
609		       bus_size_t offset, u_int8_t value)
610{
611#if defined(_I386_BUS_PIO_H_)
612#if defined(_I386_BUS_MEMIO_H_)
613	if (tag == I386_BUS_SPACE_IO)
614#endif
615		outb(bsh + offset, value);
616#endif
617#if defined(_I386_BUS_MEMIO_H_)
618#if defined(_I386_BUS_PIO_H_)
619	else
620#endif
621		*(volatile u_int8_t *)(bsh + offset) = value;
622#endif
623}
624
625static __inline void
626bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
627		       bus_size_t offset, u_int16_t value)
628{
629#if defined(_I386_BUS_PIO_H_)
630#if defined(_I386_BUS_MEMIO_H_)
631	if (tag == I386_BUS_SPACE_IO)
632#endif
633		outw(bsh + offset, value);
634#endif
635#if defined(_I386_BUS_MEMIO_H_)
636#if defined(_I386_BUS_PIO_H_)
637	else
638#endif
639		*(volatile u_int16_t *)(bsh + offset) = value;
640#endif
641}
642
643static __inline void
644bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
645		       bus_size_t offset, u_int32_t value)
646{
647#if defined(_I386_BUS_PIO_H_)
648#if defined(_I386_BUS_MEMIO_H_)
649	if (tag == I386_BUS_SPACE_IO)
650#endif
651		outl(bsh + offset, value);
652#endif
653#if defined(_I386_BUS_MEMIO_H_)
654#if defined(_I386_BUS_PIO_H_)
655	else
656#endif
657		*(volatile u_int32_t *)(bsh + offset) = value;
658#endif
659}
660
661#if 0	/* Cause a link error for bus_space_write_8 */
662#define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
663#endif
664
665/*
666 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
667 * provided to bus space described by tag/handle/offset.
668 */
669
670static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
671					     bus_space_handle_t bsh,
672					     bus_size_t offset,
673					     const u_int8_t *addr,
674					     size_t count);
675static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
676					     bus_space_handle_t bsh,
677					     bus_size_t offset,
678					     const u_int16_t *addr,
679					     size_t count);
680
681static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
682					     bus_space_handle_t bsh,
683					     bus_size_t offset,
684					     const u_int32_t *addr,
685					     size_t count);
686
687static __inline void
688bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
689			bus_size_t offset, const u_int8_t *addr, size_t count)
690{
691#if defined(_I386_BUS_PIO_H_)
692#if defined(_I386_BUS_MEMIO_H_)
693	if (tag == I386_BUS_SPACE_IO)
694#endif
695		outsb(bsh + offset, addr, count);
696#endif
697#if defined(_I386_BUS_MEMIO_H_)
698#if defined(_I386_BUS_PIO_H_)
699	else
700#endif
701	{
702#ifdef __GNUCLIKE_ASM
703		__asm __volatile("				\n\
704			cld					\n\
705		1:	lodsb					\n\
706			movb %%al,(%2)				\n\
707			loop 1b"				:
708		    "=S" (addr), "=c" (count)			:
709		    "r" (bsh + offset), "0" (addr), "1" (count)	:
710		    "%eax", "memory", "cc");
711#else
712# ifndef lint
713#  error "no assembler code for your compiler"
714# endif
715#endif
716	}
717#endif
718}
719
720static __inline void
721bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
722			bus_size_t offset, const u_int16_t *addr, size_t count)
723{
724#if defined(_I386_BUS_PIO_H_)
725#if defined(_I386_BUS_MEMIO_H_)
726	if (tag == I386_BUS_SPACE_IO)
727#endif
728		outsw(bsh + offset, addr, count);
729#endif
730#if defined(_I386_BUS_MEMIO_H_)
731#if defined(_I386_BUS_PIO_H_)
732	else
733#endif
734	{
735#ifdef __GNUCLIKE_ASM
736		__asm __volatile("				\n\
737			cld					\n\
738		1:	lodsw					\n\
739			movw %%ax,(%2)				\n\
740			loop 1b"				:
741		    "=S" (addr), "=c" (count)			:
742		    "r" (bsh + offset), "0" (addr), "1" (count)	:
743		    "%eax", "memory", "cc");
744#else
745# ifndef lint
746#  error "no assembler code for your compiler"
747# endif
748#endif
749	}
750#endif
751}
752
753static __inline void
754bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
755			bus_size_t offset, const u_int32_t *addr, size_t count)
756{
757#if defined(_I386_BUS_PIO_H_)
758#if defined(_I386_BUS_MEMIO_H_)
759	if (tag == I386_BUS_SPACE_IO)
760#endif
761		outsl(bsh + offset, addr, count);
762#endif
763#if defined(_I386_BUS_MEMIO_H_)
764#if defined(_I386_BUS_PIO_H_)
765	else
766#endif
767	{
768#ifdef __GNUCLIKE_ASM
769		__asm __volatile("				\n\
770			cld					\n\
771		1:	lodsl					\n\
772			movl %%eax,(%2)				\n\
773			loop 1b"				:
774		    "=S" (addr), "=c" (count)			:
775		    "r" (bsh + offset), "0" (addr), "1" (count)	:
776		    "%eax", "memory", "cc");
777#else
778# ifndef lint
779#  error "no assembler code for your compiler"
780# endif
781#endif
782	}
783#endif
784}
785
786#if 0	/* Cause a link error for bus_space_write_multi_8 */
787#define	bus_space_write_multi_8(t, h, o, a, c)				\
788			!!! bus_space_write_multi_8 unimplemented !!!
789#endif
790
791/*
792 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
793 * to bus space described by tag/handle starting at `offset'.
794 */
795
796static __inline void bus_space_write_region_1(bus_space_tag_t tag,
797					      bus_space_handle_t bsh,
798					      bus_size_t offset,
799					      const u_int8_t *addr,
800					      size_t count);
801static __inline void bus_space_write_region_2(bus_space_tag_t tag,
802					      bus_space_handle_t bsh,
803					      bus_size_t offset,
804					      const u_int16_t *addr,
805					      size_t count);
806static __inline void bus_space_write_region_4(bus_space_tag_t tag,
807					      bus_space_handle_t bsh,
808					      bus_size_t offset,
809					      const u_int32_t *addr,
810					      size_t count);
811
812static __inline void
813bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
814			 bus_size_t offset, const u_int8_t *addr, size_t count)
815{
816#if defined(_I386_BUS_PIO_H_)
817#if defined(_I386_BUS_MEMIO_H_)
818	if (tag == I386_BUS_SPACE_IO)
819#endif
820	{
821		int _port_ = bsh + offset;
822#ifdef __GNUCLIKE_ASM
823		__asm __volatile("				\n\
824			cld					\n\
825		1:	lodsb					\n\
826			outb %%al,%w0				\n\
827			incl %0					\n\
828			loop 1b"				:
829		    "=d" (_port_), "=S" (addr), "=c" (count)	:
830		    "0" (_port_), "1" (addr), "2" (count)	:
831		    "%eax", "memory", "cc");
832#else
833# ifndef lint
834#  error "no assembler code for your compiler"
835# endif
836#endif
837	}
838#endif
839#if defined(_I386_BUS_MEMIO_H_)
840#if defined(_I386_BUS_PIO_H_)
841	else
842#endif
843	{
844		int _port_ = bsh + offset;
845#ifdef __GNUCLIKE_ASM
846		__asm __volatile("				\n\
847			cld					\n\
848			repne					\n\
849			movsb"					:
850		    "=D" (_port_), "=S" (addr), "=c" (count)	:
851		    "0" (_port_), "1" (addr), "2" (count)	:
852		    "memory", "cc");
853#else
854# ifndef lint
855#  error "no assembler code for your compiler"
856# endif
857#endif
858	}
859#endif
860}
861
862static __inline void
863bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
864			 bus_size_t offset, const u_int16_t *addr, size_t count)
865{
866#if defined(_I386_BUS_PIO_H_)
867#if defined(_I386_BUS_MEMIO_H_)
868	if (tag == I386_BUS_SPACE_IO)
869#endif
870	{
871		int _port_ = bsh + offset;
872#ifdef __GNUCLIKE_ASM
873		__asm __volatile("				\n\
874			cld					\n\
875		1:	lodsw					\n\
876			outw %%ax,%w0				\n\
877			addl $2,%0				\n\
878			loop 1b"				:
879		    "=d" (_port_), "=S" (addr), "=c" (count)	:
880		    "0" (_port_), "1" (addr), "2" (count)	:
881		    "%eax", "memory", "cc");
882#else
883# ifndef lint
884#  error "no assembler code for your compiler"
885# endif
886#endif
887	}
888#endif
889#if defined(_I386_BUS_MEMIO_H_)
890#if defined(_I386_BUS_PIO_H_)
891	else
892#endif
893	{
894		int _port_ = bsh + offset;
895#ifdef __GNUCLIKE_ASM
896		__asm __volatile("				\n\
897			cld					\n\
898			repne					\n\
899			movsw"					:
900		    "=D" (_port_), "=S" (addr), "=c" (count)	:
901		    "0" (_port_), "1" (addr), "2" (count)	:
902		    "memory", "cc");
903#else
904# ifndef lint
905#  error "no assembler code for your compiler"
906# endif
907#endif
908	}
909#endif
910}
911
912static __inline void
913bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
914			 bus_size_t offset, const u_int32_t *addr, size_t count)
915{
916#if defined(_I386_BUS_PIO_H_)
917#if defined(_I386_BUS_MEMIO_H_)
918	if (tag == I386_BUS_SPACE_IO)
919#endif
920	{
921		int _port_ = bsh + offset;
922#ifdef __GNUCLIKE_ASM
923		__asm __volatile("				\n\
924			cld					\n\
925		1:	lodsl					\n\
926			outl %%eax,%w0				\n\
927			addl $4,%0				\n\
928			loop 1b"				:
929		    "=d" (_port_), "=S" (addr), "=c" (count)	:
930		    "0" (_port_), "1" (addr), "2" (count)	:
931		    "%eax", "memory", "cc");
932#else
933# ifndef lint
934#  error "no assembler code for your compiler"
935# endif
936#endif
937	}
938#endif
939#if defined(_I386_BUS_MEMIO_H_)
940#if defined(_I386_BUS_PIO_H_)
941	else
942#endif
943	{
944		int _port_ = bsh + offset;
945#ifdef __GNUCLIKE_ASM
946		__asm __volatile("				\n\
947			cld					\n\
948			repne					\n\
949			movsl"					:
950		    "=D" (_port_), "=S" (addr), "=c" (count)	:
951		    "0" (_port_), "1" (addr), "2" (count)	:
952		    "memory", "cc");
953#else
954# ifndef lint
955#  error "no assembler code for your compiler"
956# endif
957#endif
958	}
959#endif
960}
961
962#if 0	/* Cause a link error for bus_space_write_region_8 */
963#define	bus_space_write_region_8					\
964			!!! bus_space_write_region_8 unimplemented !!!
965#endif
966
967/*
968 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
969 * by tag/handle/offset `count' times.
970 */
971
972static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
973					   bus_space_handle_t bsh,
974					   bus_size_t offset,
975					   u_int8_t value, size_t count);
976static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
977					   bus_space_handle_t bsh,
978					   bus_size_t offset,
979					   u_int16_t value, size_t count);
980static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
981					   bus_space_handle_t bsh,
982					   bus_size_t offset,
983					   u_int32_t value, size_t count);
984
985static __inline void
986bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
987		      bus_size_t offset, u_int8_t value, size_t count)
988{
989	bus_space_handle_t addr = bsh + offset;
990
991#if defined(_I386_BUS_PIO_H_)
992#if defined(_I386_BUS_MEMIO_H_)
993	if (tag == I386_BUS_SPACE_IO)
994#endif
995		while (count--)
996			outb(addr, value);
997#endif
998#if defined(_I386_BUS_MEMIO_H_)
999#if defined(_I386_BUS_PIO_H_)
1000	else
1001#endif
1002		while (count--)
1003			*(volatile u_int8_t *)(addr) = value;
1004#endif
1005}
1006
1007static __inline void
1008bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
1009		     bus_size_t offset, u_int16_t value, size_t count)
1010{
1011	bus_space_handle_t addr = bsh + offset;
1012
1013#if defined(_I386_BUS_PIO_H_)
1014#if defined(_I386_BUS_MEMIO_H_)
1015	if (tag == I386_BUS_SPACE_IO)
1016#endif
1017		while (count--)
1018			outw(addr, value);
1019#endif
1020#if defined(_I386_BUS_MEMIO_H_)
1021#if defined(_I386_BUS_PIO_H_)
1022	else
1023#endif
1024		while (count--)
1025			*(volatile u_int16_t *)(addr) = value;
1026#endif
1027}
1028
1029static __inline void
1030bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
1031		      bus_size_t offset, u_int32_t value, size_t count)
1032{
1033	bus_space_handle_t addr = bsh + offset;
1034
1035#if defined(_I386_BUS_PIO_H_)
1036#if defined(_I386_BUS_MEMIO_H_)
1037	if (tag == I386_BUS_SPACE_IO)
1038#endif
1039		while (count--)
1040			outl(addr, value);
1041#endif
1042#if defined(_I386_BUS_MEMIO_H_)
1043#if defined(_I386_BUS_PIO_H_)
1044	else
1045#endif
1046		while (count--)
1047			*(volatile u_int32_t *)(addr) = value;
1048#endif
1049}
1050
1051#if 0	/* Cause a link error for bus_space_set_multi_8 */
1052#define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
1053#endif
1054
1055/*
1056 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
1057 * by tag/handle starting at `offset'.
1058 */
1059
1060static __inline void bus_space_set_region_1(bus_space_tag_t tag,
1061					    bus_space_handle_t bsh,
1062					    bus_size_t offset, u_int8_t value,
1063					    size_t count);
1064static __inline void bus_space_set_region_2(bus_space_tag_t tag,
1065					    bus_space_handle_t bsh,
1066					    bus_size_t offset, u_int16_t value,
1067					    size_t count);
1068static __inline void bus_space_set_region_4(bus_space_tag_t tag,
1069					    bus_space_handle_t bsh,
1070					    bus_size_t offset, u_int32_t value,
1071					    size_t count);
1072
1073static __inline void
1074bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
1075		       bus_size_t offset, u_int8_t value, size_t count)
1076{
1077	bus_space_handle_t addr = bsh + offset;
1078
1079#if defined(_I386_BUS_PIO_H_)
1080#if defined(_I386_BUS_MEMIO_H_)
1081	if (tag == I386_BUS_SPACE_IO)
1082#endif
1083		for (; count != 0; count--, addr++)
1084			outb(addr, value);
1085#endif
1086#if defined(_I386_BUS_MEMIO_H_)
1087#if defined(_I386_BUS_PIO_H_)
1088	else
1089#endif
1090		for (; count != 0; count--, addr++)
1091			*(volatile u_int8_t *)(addr) = value;
1092#endif
1093}
1094
1095static __inline void
1096bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
1097		       bus_size_t offset, u_int16_t value, size_t count)
1098{
1099	bus_space_handle_t addr = bsh + offset;
1100
1101#if defined(_I386_BUS_PIO_H_)
1102#if defined(_I386_BUS_MEMIO_H_)
1103	if (tag == I386_BUS_SPACE_IO)
1104#endif
1105		for (; count != 0; count--, addr += 2)
1106			outw(addr, value);
1107#endif
1108#if defined(_I386_BUS_MEMIO_H_)
1109#if defined(_I386_BUS_PIO_H_)
1110	else
1111#endif
1112		for (; count != 0; count--, addr += 2)
1113			*(volatile u_int16_t *)(addr) = value;
1114#endif
1115}
1116
1117static __inline void
1118bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
1119		       bus_size_t offset, u_int32_t value, size_t count)
1120{
1121	bus_space_handle_t addr = bsh + offset;
1122
1123#if defined(_I386_BUS_PIO_H_)
1124#if defined(_I386_BUS_MEMIO_H_)
1125	if (tag == I386_BUS_SPACE_IO)
1126#endif
1127		for (; count != 0; count--, addr += 4)
1128			outl(addr, value);
1129#endif
1130#if defined(_I386_BUS_MEMIO_H_)
1131#if defined(_I386_BUS_PIO_H_)
1132	else
1133#endif
1134		for (; count != 0; count--, addr += 4)
1135			*(volatile u_int32_t *)(addr) = value;
1136#endif
1137}
1138
1139#if 0	/* Cause a link error for bus_space_set_region_8 */
1140#define	bus_space_set_region_8	!!! bus_space_set_region_8 unimplemented !!!
1141#endif
1142
1143/*
1144 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
1145 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
1146 */
1147
1148static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
1149					     bus_space_handle_t bsh1,
1150					     bus_size_t off1,
1151					     bus_space_handle_t bsh2,
1152					     bus_size_t off2, size_t count);
1153
1154static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
1155					     bus_space_handle_t bsh1,
1156					     bus_size_t off1,
1157					     bus_space_handle_t bsh2,
1158					     bus_size_t off2, size_t count);
1159
1160static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
1161					     bus_space_handle_t bsh1,
1162					     bus_size_t off1,
1163					     bus_space_handle_t bsh2,
1164					     bus_size_t off2, size_t count);
1165
1166static __inline void
1167bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
1168			bus_size_t off1, bus_space_handle_t bsh2,
1169			bus_size_t off2, size_t count)
1170{
1171	bus_space_handle_t addr1 = bsh1 + off1;
1172	bus_space_handle_t addr2 = bsh2 + off2;
1173
1174#if defined(_I386_BUS_PIO_H_)
1175#if defined(_I386_BUS_MEMIO_H_)
1176	if (tag == I386_BUS_SPACE_IO)
1177#endif
1178	{
1179		if (addr1 >= addr2) {
1180			/* src after dest: copy forward */
1181			for (; count != 0; count--, addr1++, addr2++)
1182				outb(addr2, inb(addr1));
1183		} else {
1184			/* dest after src: copy backwards */
1185			for (addr1 += (count - 1), addr2 += (count - 1);
1186			    count != 0; count--, addr1--, addr2--)
1187				outb(addr2, inb(addr1));
1188		}
1189	}
1190#endif
1191#if defined(_I386_BUS_MEMIO_H_)
1192#if defined(_I386_BUS_PIO_H_)
1193	else
1194#endif
1195	{
1196		if (addr1 >= addr2) {
1197			/* src after dest: copy forward */
1198			for (; count != 0; count--, addr1++, addr2++)
1199				*(volatile u_int8_t *)(addr2) =
1200				    *(volatile u_int8_t *)(addr1);
1201		} else {
1202			/* dest after src: copy backwards */
1203			for (addr1 += (count - 1), addr2 += (count - 1);
1204			    count != 0; count--, addr1--, addr2--)
1205				*(volatile u_int8_t *)(addr2) =
1206				    *(volatile u_int8_t *)(addr1);
1207		}
1208	}
1209#endif
1210}
1211
1212static __inline void
1213bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
1214			bus_size_t off1, bus_space_handle_t bsh2,
1215			bus_size_t off2, size_t count)
1216{
1217	bus_space_handle_t addr1 = bsh1 + off1;
1218	bus_space_handle_t addr2 = bsh2 + off2;
1219
1220#if defined(_I386_BUS_PIO_H_)
1221#if defined(_I386_BUS_MEMIO_H_)
1222	if (tag == I386_BUS_SPACE_IO)
1223#endif
1224	{
1225		if (addr1 >= addr2) {
1226			/* src after dest: copy forward */
1227			for (; count != 0; count--, addr1 += 2, addr2 += 2)
1228				outw(addr2, inw(addr1));
1229		} else {
1230			/* dest after src: copy backwards */
1231			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1232			    count != 0; count--, addr1 -= 2, addr2 -= 2)
1233				outw(addr2, inw(addr1));
1234		}
1235	}
1236#endif
1237#if defined(_I386_BUS_MEMIO_H_)
1238#if defined(_I386_BUS_PIO_H_)
1239	else
1240#endif
1241	{
1242		if (addr1 >= addr2) {
1243			/* src after dest: copy forward */
1244			for (; count != 0; count--, addr1 += 2, addr2 += 2)
1245				*(volatile u_int16_t *)(addr2) =
1246				    *(volatile u_int16_t *)(addr1);
1247		} else {
1248			/* dest after src: copy backwards */
1249			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1250			    count != 0; count--, addr1 -= 2, addr2 -= 2)
1251				*(volatile u_int16_t *)(addr2) =
1252				    *(volatile u_int16_t *)(addr1);
1253		}
1254	}
1255#endif
1256}
1257
1258static __inline void
1259bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
1260			bus_size_t off1, bus_space_handle_t bsh2,
1261			bus_size_t off2, size_t count)
1262{
1263	bus_space_handle_t addr1 = bsh1 + off1;
1264	bus_space_handle_t addr2 = bsh2 + off2;
1265
1266#if defined(_I386_BUS_PIO_H_)
1267#if defined(_I386_BUS_MEMIO_H_)
1268	if (tag == I386_BUS_SPACE_IO)
1269#endif
1270	{
1271		if (addr1 >= addr2) {
1272			/* src after dest: copy forward */
1273			for (; count != 0; count--, addr1 += 4, addr2 += 4)
1274				outl(addr2, inl(addr1));
1275		} else {
1276			/* dest after src: copy backwards */
1277			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1278			    count != 0; count--, addr1 -= 4, addr2 -= 4)
1279				outl(addr2, inl(addr1));
1280		}
1281	}
1282#endif
1283#if defined(_I386_BUS_MEMIO_H_)
1284#if defined(_I386_BUS_PIO_H_)
1285	else
1286#endif
1287	{
1288		if (addr1 >= addr2) {
1289			/* src after dest: copy forward */
1290			for (; count != 0; count--, addr1 += 4, addr2 += 4)
1291				*(volatile u_int32_t *)(addr2) =
1292				    *(volatile u_int32_t *)(addr1);
1293		} else {
1294			/* dest after src: copy backwards */
1295			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1296			    count != 0; count--, addr1 -= 4, addr2 -= 4)
1297				*(volatile u_int32_t *)(addr2) =
1298				    *(volatile u_int32_t *)(addr1);
1299		}
1300	}
1301#endif
1302}
1303
1304#endif /* defined(_I386_BUS_PIO_H_) || defined(_I386_MEM_IO_H_) */
1305
1306#if 0	/* Cause a link error for bus_space_copy_8 */
1307#define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
1308#endif
1309
1310/*
1311 * Bus read/write barrier methods.
1312 *
1313 *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
1314 *			       bus_size_t offset, bus_size_t len, int flags);
1315 *
1316 *
1317 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
1318 * prevent reordering by the compiler; all Intel x86 processors currently
1319 * retire operations outside the CPU in program order.
1320 */
1321#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
1322#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
1323
1324static __inline void
1325bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
1326		  bus_size_t offset __unused, bus_size_t len __unused, int flags)
1327{
1328#ifdef __GNUCLIKE_ASM
1329	if (flags & BUS_SPACE_BARRIER_READ)
1330		__asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
1331	else
1332		__asm __volatile("" : : : "memory");
1333#else
1334# ifndef lint
1335#  error "no assembler code for your compiler"
1336# endif
1337#endif
1338}
1339
1340#if BUS_SPACE_NO_LEGACY
1341#undef inb
1342#undef outb
1343#define inb(a) compiler_error
1344#define inw(a) compiler_error
1345#define inl(a) compiler_error
1346#define outb(a, b) compiler_error
1347#define outw(a, b) compiler_error
1348#define outl(a, b) compiler_error
1349#endif
1350
1351#include <machine/bus_dma.h>
1352
1353/*
1354 * Stream accesses are the same as normal accesses on i386/pc98; there are no
1355 * supported bus systems with an endianess different from the host one.
1356 */
1357#define	bus_space_read_stream_1(t, h, o)	bus_space_read_1((t), (h), (o))
1358#define	bus_space_read_stream_2(t, h, o)	bus_space_read_2((t), (h), (o))
1359#define	bus_space_read_stream_4(t, h, o)	bus_space_read_4((t), (h), (o))
1360
1361#define	bus_space_read_multi_stream_1(t, h, o, a, c) \
1362	bus_space_read_multi_1((t), (h), (o), (a), (c))
1363#define	bus_space_read_multi_stream_2(t, h, o, a, c) \
1364	bus_space_read_multi_2((t), (h), (o), (a), (c))
1365#define	bus_space_read_multi_stream_4(t, h, o, a, c) \
1366	bus_space_read_multi_4((t), (h), (o), (a), (c))
1367
1368#define	bus_space_write_stream_1(t, h, o, v) \
1369	bus_space_write_1((t), (h), (o), (v))
1370#define	bus_space_write_stream_2(t, h, o, v) \
1371	bus_space_write_2((t), (h), (o), (v))
1372#define	bus_space_write_stream_4(t, h, o, v) \
1373	bus_space_write_4((t), (h), (o), (v))
1374
1375#define	bus_space_write_multi_stream_1(t, h, o, a, c) \
1376	bus_space_write_multi_1((t), (h), (o), (a), (c))
1377#define	bus_space_write_multi_stream_2(t, h, o, a, c) \
1378	bus_space_write_multi_2((t), (h), (o), (a), (c))
1379#define	bus_space_write_multi_stream_4(t, h, o, a, c) \
1380	bus_space_write_multi_4((t), (h), (o), (a), (c))
1381
1382#define	bus_space_set_multi_stream_1(t, h, o, v, c) \
1383	bus_space_set_multi_1((t), (h), (o), (v), (c))
1384#define	bus_space_set_multi_stream_2(t, h, o, v, c) \
1385	bus_space_set_multi_2((t), (h), (o), (v), (c))
1386#define	bus_space_set_multi_stream_4(t, h, o, v, c) \
1387	bus_space_set_multi_4((t), (h), (o), (v), (c))
1388
1389#define	bus_space_read_region_stream_1(t, h, o, a, c) \
1390	bus_space_read_region_1((t), (h), (o), (a), (c))
1391#define	bus_space_read_region_stream_2(t, h, o, a, c) \
1392	bus_space_read_region_2((t), (h), (o), (a), (c))
1393#define	bus_space_read_region_stream_4(t, h, o, a, c) \
1394	bus_space_read_region_4((t), (h), (o), (a), (c))
1395
1396#define	bus_space_write_region_stream_1(t, h, o, a, c) \
1397	bus_space_write_region_1((t), (h), (o), (a), (c))
1398#define	bus_space_write_region_stream_2(t, h, o, a, c) \
1399	bus_space_write_region_2((t), (h), (o), (a), (c))
1400#define	bus_space_write_region_stream_4(t, h, o, a, c) \
1401	bus_space_write_region_4((t), (h), (o), (a), (c))
1402
1403#define	bus_space_set_region_stream_1(t, h, o, v, c) \
1404	bus_space_set_region_1((t), (h), (o), (v), (c))
1405#define	bus_space_set_region_stream_2(t, h, o, v, c) \
1406	bus_space_set_region_2((t), (h), (o), (v), (c))
1407#define	bus_space_set_region_stream_4(t, h, o, v, c) \
1408	bus_space_set_region_4((t), (h), (o), (v), (c))
1409
1410#define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
1411	bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
1412#define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
1413	bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
1414#define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
1415	bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
1416
1417#endif /* _I386_BUS_H_ */
1418