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