bus.h revision 241374
132517Sgibbs/*-
258762Skato * Copyright (c) KATO Takenori, 1999.
332517Sgibbs *
458762Skato * All rights reserved.  Unpublished rights reserved under the copyright
558762Skato * laws of Japan.
632517Sgibbs *
732517Sgibbs * Redistribution and use in source and binary forms, with or without
832517Sgibbs * modification, are permitted provided that the following conditions
932517Sgibbs * are met:
1058762Skato *
1132517Sgibbs * 1. Redistributions of source code must retain the above copyright
1258762Skato *    notice, this list of conditions and the following disclaimer as
1358762Skato *    the first lines of this file unmodified.
1432517Sgibbs * 2. Redistributions in binary form must reproduce the above copyright
1532517Sgibbs *    notice, this list of conditions and the following disclaimer in the
1632517Sgibbs *    documentation and/or other materials provided with the distribution.
1758762Skato * 3. The name of the author may not be used to endorse or promote products
1858762Skato *    derived from this software without specific prior written permission.
1958762Skato *
2032517Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2132517Sgibbs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2232517Sgibbs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2332517Sgibbs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2432517Sgibbs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2532517Sgibbs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2632517Sgibbs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2732517Sgibbs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2832517Sgibbs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2932517Sgibbs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3058762Skato *
3158762Skato * $FreeBSD: head/sys/x86/include/bus.h 241374 2012-10-09 14:32:30Z attilio $
3232517Sgibbs */
3332517Sgibbs
34145119Speter/*	$NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $	*/
35145119Speter
36145119Speter/*-
37145119Speter * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
38145119Speter * All rights reserved.
39145119Speter *
40145119Speter * This code is derived from software contributed to The NetBSD Foundation
41145119Speter * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
42145119Speter * NASA Ames Research Center.
43145119Speter *
44145119Speter * Redistribution and use in source and binary forms, with or without
45145119Speter * modification, are permitted provided that the following conditions
46145119Speter * are met:
47145119Speter * 1. Redistributions of source code must retain the above copyright
48145119Speter *    notice, this list of conditions and the following disclaimer.
49145119Speter * 2. Redistributions in binary form must reproduce the above copyright
50145119Speter *    notice, this list of conditions and the following disclaimer in the
51145119Speter *    documentation and/or other materials provided with the distribution.
52145119Speter * 3. All advertising materials mentioning features or use of this software
53145119Speter *    must display the following acknowledgement:
54145119Speter *	This product includes software developed by the NetBSD
55145119Speter *	Foundation, Inc. and its contributors.
56145119Speter * 4. Neither the name of The NetBSD Foundation nor the names of its
57145119Speter *    contributors may be used to endorse or promote products derived
58145119Speter *    from this software without specific prior written permission.
59145119Speter *
60145119Speter * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
61145119Speter * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
62145119Speter * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63145119Speter * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
64145119Speter * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
65145119Speter * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
66145119Speter * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
67145119Speter * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
68145119Speter * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
69145119Speter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
70145119Speter * POSSIBILITY OF SUCH DAMAGE.
71145119Speter */
72145119Speter
73145119Speter/*-
74145119Speter * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
75145119Speter * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
76145119Speter *
77145119Speter * Redistribution and use in source and binary forms, with or without
78145119Speter * modification, are permitted provided that the following conditions
79145119Speter * are met:
80145119Speter * 1. Redistributions of source code must retain the above copyright
81145119Speter *    notice, this list of conditions and the following disclaimer.
82145119Speter * 2. Redistributions in binary form must reproduce the above copyright
83145119Speter *    notice, this list of conditions and the following disclaimer in the
84145119Speter *    documentation and/or other materials provided with the distribution.
85145119Speter * 3. All advertising materials mentioning features or use of this software
86145119Speter *    must display the following acknowledgement:
87145119Speter *      This product includes software developed by Christopher G. Demetriou
88145119Speter *	for the NetBSD Project.
89145119Speter * 4. The name of the author may not be used to endorse or promote products
90145119Speter *    derived from this software without specific prior written permission
91145119Speter *
92145119Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
93145119Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
94145119Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
95145119Speter * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
96145119Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97145119Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98145119Speter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
99145119Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100145119Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
101145119Speter * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102145119Speter */
103145119Speter
104216592Stijl#ifndef _X86_BUS_H_
105216592Stijl#define _X86_BUS_H_
10632517Sgibbs
107145253Simp#include <machine/_bus.h>
108145119Speter#include <machine/cpufunc.h>
109145119Speter
110216592Stijl#ifndef __GNUCLIKE_ASM
111216592Stijl# ifndef lint
112216592Stijl#  error "no assembler code for your compiler"
113216592Stijl# endif
114216592Stijl#endif
115216592Stijl
116145119Speter/*
117216592Stijl * Values for the x86 bus space tag, not to be used directly by MI code.
118145119Speter */
119216592Stijl#define	X86_BUS_SPACE_IO	0	/* space is i/o space */
120216592Stijl#define	X86_BUS_SPACE_MEM	1	/* space is mem space */
121145119Speter
122145119Speter#define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
123145119Speter#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
124145119Speter#define BUS_SPACE_MAXSIZE	0xFFFFFFFF
125145119Speter#define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
126145119Speter#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
127216592Stijl#if defined(__amd64__) || defined(PAE)
128145119Speter#define BUS_SPACE_MAXADDR	0xFFFFFFFFFFFFFFFFULL
129216592Stijl#else
130216592Stijl#define BUS_SPACE_MAXADDR	0xFFFFFFFF
131216592Stijl#endif
132145119Speter
133145119Speter#define BUS_SPACE_UNRESTRICTED	(~0)
134145119Speter
135145119Speter/*
136145119Speter * Map a region of device bus space into CPU virtual address space.
137145119Speter */
138145119Speter
139145119Speterstatic __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
140145119Speter				  bus_size_t size, int flags,
141145119Speter				  bus_space_handle_t *bshp);
142145119Speter
143145119Speterstatic __inline int
144145119Speterbus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
145145119Speter	      bus_size_t size __unused, int flags __unused,
146145119Speter	      bus_space_handle_t *bshp)
147145119Speter{
148145119Speter
149145119Speter	*bshp = addr;
150145119Speter	return (0);
151145119Speter}
152145119Speter
153145119Speter/*
154145119Speter * Unmap a region of device bus space.
155145119Speter */
156145119Speter
157145119Speterstatic __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
158145119Speter				     bus_size_t size);
159145119Speter
160145119Speterstatic __inline void
161145119Speterbus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
162145119Speter		bus_size_t size __unused)
163145119Speter{
164145119Speter}
165145119Speter
166145119Speter/*
167145119Speter * Get a new handle for a subregion of an already-mapped area of bus space.
168145119Speter */
169145119Speter
170145119Speterstatic __inline int bus_space_subregion(bus_space_tag_t t,
171145119Speter					bus_space_handle_t bsh,
172145119Speter					bus_size_t offset, bus_size_t size,
173145119Speter					bus_space_handle_t *nbshp);
174145119Speter
175145119Speterstatic __inline int
176145119Speterbus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
177145119Speter		    bus_size_t offset, bus_size_t size __unused,
178145119Speter		    bus_space_handle_t *nbshp)
179145119Speter{
180145119Speter
181145119Speter	*nbshp = bsh + offset;
182145119Speter	return (0);
183145119Speter}
184145119Speter
185145119Speter/*
186145119Speter * Allocate a region of memory that is accessible to devices in bus space.
187145119Speter */
188145119Speter
189145119Speterint	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
190145119Speter			bus_addr_t rend, bus_size_t size, bus_size_t align,
191145119Speter			bus_size_t boundary, int flags, bus_addr_t *addrp,
192145119Speter			bus_space_handle_t *bshp);
193145119Speter
194145119Speter/*
195145119Speter * Free a region of bus space accessible memory.
196145119Speter */
197145119Speter
198145119Speterstatic __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
199145119Speter				    bus_size_t size);
200145119Speter
201145119Speterstatic __inline void
202145119Speterbus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
203145119Speter	       bus_size_t size __unused)
204145119Speter{
205145119Speter}
206145119Speter
207145119Speter
208145119Speter/*
209145119Speter * Read a 1, 2, 4, or 8 byte quantity from bus space
210145119Speter * described by tag/handle/offset.
211145119Speter */
212145119Speterstatic __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
213145119Speter					  bus_space_handle_t handle,
214145119Speter					  bus_size_t offset);
215145119Speter
216145119Speterstatic __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
217145119Speter					   bus_space_handle_t handle,
218145119Speter					   bus_size_t offset);
219145119Speter
220145119Speterstatic __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
221145119Speter					   bus_space_handle_t handle,
222145119Speter					   bus_size_t offset);
223145119Speter
224145119Speterstatic __inline u_int8_t
225145119Speterbus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
226145119Speter		 bus_size_t offset)
227145119Speter{
228146734Snyan
229216592Stijl	if (tag == X86_BUS_SPACE_IO)
230145119Speter		return (inb(handle + offset));
231145119Speter	return (*(volatile u_int8_t *)(handle + offset));
232145119Speter}
233145119Speter
234145119Speterstatic __inline u_int16_t
235145119Speterbus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
236145119Speter		 bus_size_t offset)
237145119Speter{
238146734Snyan
239216592Stijl	if (tag == X86_BUS_SPACE_IO)
240145119Speter		return (inw(handle + offset));
241145119Speter	return (*(volatile u_int16_t *)(handle + offset));
242145119Speter}
243145119Speter
244145119Speterstatic __inline u_int32_t
245145119Speterbus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
246145119Speter		 bus_size_t offset)
247145119Speter{
248146734Snyan
249216592Stijl	if (tag == X86_BUS_SPACE_IO)
250145119Speter		return (inl(handle + offset));
251145119Speter	return (*(volatile u_int32_t *)(handle + offset));
252145119Speter}
253145119Speter
254145119Speter#if 0	/* Cause a link error for bus_space_read_8 */
255145119Speter#define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
256145119Speter#endif
257145119Speter
258145119Speter/*
259145119Speter * Read `count' 1, 2, 4, or 8 byte quantities from bus space
260145119Speter * described by tag/handle/offset and copy into buffer provided.
261145119Speter */
262145119Speterstatic __inline void bus_space_read_multi_1(bus_space_tag_t tag,
263145119Speter					    bus_space_handle_t bsh,
264145119Speter					    bus_size_t offset, u_int8_t *addr,
265145119Speter					    size_t count);
266145119Speter
267145119Speterstatic __inline void bus_space_read_multi_2(bus_space_tag_t tag,
268145119Speter					    bus_space_handle_t bsh,
269145119Speter					    bus_size_t offset, u_int16_t *addr,
270145119Speter					    size_t count);
271145119Speter
272145119Speterstatic __inline void bus_space_read_multi_4(bus_space_tag_t tag,
273145119Speter					    bus_space_handle_t bsh,
274145119Speter					    bus_size_t offset, u_int32_t *addr,
275145119Speter					    size_t count);
276145119Speter
277145119Speterstatic __inline void
278145119Speterbus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
279145119Speter		       bus_size_t offset, u_int8_t *addr, size_t count)
280145119Speter{
281216143Sbrucec
282216592Stijl	if (tag == X86_BUS_SPACE_IO)
283145119Speter		insb(bsh + offset, addr, count);
284146734Snyan	else {
285145119Speter#ifdef __GNUCLIKE_ASM
286145119Speter		__asm __volatile("				\n\
287145119Speter			cld					\n\
288145119Speter		1:	movb (%2),%%al				\n\
289145119Speter			stosb					\n\
290145119Speter			loop 1b"				:
291145119Speter		    "=D" (addr), "=c" (count)			:
292145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
293145119Speter		    "%eax", "memory");
294145119Speter#endif
295145119Speter	}
296145119Speter}
297145119Speter
298145119Speterstatic __inline void
299145119Speterbus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
300145119Speter		       bus_size_t offset, u_int16_t *addr, size_t count)
301145119Speter{
302216143Sbrucec
303216592Stijl	if (tag == X86_BUS_SPACE_IO)
304145119Speter		insw(bsh + offset, addr, count);
305146734Snyan	else {
306145119Speter#ifdef __GNUCLIKE_ASM
307145119Speter		__asm __volatile("				\n\
308145119Speter			cld					\n\
309145119Speter		1:	movw (%2),%%ax				\n\
310145119Speter			stosw					\n\
311145119Speter			loop 1b"				:
312145119Speter		    "=D" (addr), "=c" (count)			:
313145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
314145119Speter		    "%eax", "memory");
315145119Speter#endif
316145119Speter	}
317145119Speter}
318145119Speter
319145119Speterstatic __inline void
320145119Speterbus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
321145119Speter		       bus_size_t offset, u_int32_t *addr, size_t count)
322145119Speter{
323216143Sbrucec
324216592Stijl	if (tag == X86_BUS_SPACE_IO)
325145119Speter		insl(bsh + offset, addr, count);
326146734Snyan	else {
327145119Speter#ifdef __GNUCLIKE_ASM
328145119Speter		__asm __volatile("				\n\
329145119Speter			cld					\n\
330145119Speter		1:	movl (%2),%%eax				\n\
331145119Speter			stosl					\n\
332145119Speter			loop 1b"				:
333145119Speter		    "=D" (addr), "=c" (count)			:
334145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
335145119Speter		    "%eax", "memory");
336145119Speter#endif
337145119Speter	}
338145119Speter}
339145119Speter
340145119Speter#if 0	/* Cause a link error for bus_space_read_multi_8 */
341145119Speter#define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
342145119Speter#endif
343145119Speter
344145119Speter/*
345145119Speter * Read `count' 1, 2, 4, or 8 byte quantities from bus space
346145119Speter * described by tag/handle and starting at `offset' and copy into
347145119Speter * buffer provided.
348145119Speter */
349145119Speterstatic __inline void bus_space_read_region_1(bus_space_tag_t tag,
350145119Speter					     bus_space_handle_t bsh,
351145119Speter					     bus_size_t offset, u_int8_t *addr,
352145119Speter					     size_t count);
353145119Speter
354145119Speterstatic __inline void bus_space_read_region_2(bus_space_tag_t tag,
355145119Speter					     bus_space_handle_t bsh,
356145119Speter					     bus_size_t offset, u_int16_t *addr,
357145119Speter					     size_t count);
358145119Speter
359145119Speterstatic __inline void bus_space_read_region_4(bus_space_tag_t tag,
360145119Speter					     bus_space_handle_t bsh,
361145119Speter					     bus_size_t offset, u_int32_t *addr,
362145119Speter					     size_t count);
363145119Speter
364145119Speter
365145119Speterstatic __inline void
366145119Speterbus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
367145119Speter			bus_size_t offset, u_int8_t *addr, size_t count)
368145119Speter{
369216143Sbrucec
370216592Stijl	if (tag == X86_BUS_SPACE_IO) {
371145119Speter		int _port_ = bsh + offset;
372145119Speter#ifdef __GNUCLIKE_ASM
373145119Speter		__asm __volatile("				\n\
374145119Speter			cld					\n\
375145119Speter		1:	inb %w2,%%al				\n\
376145119Speter			stosb					\n\
377145119Speter			incl %2					\n\
378145119Speter			loop 1b"				:
379145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
380145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
381145119Speter		    "%eax", "memory", "cc");
382145119Speter#endif
383146734Snyan	} else {
384145119Speter		bus_space_handle_t _port_ = bsh + offset;
385145119Speter#ifdef __GNUCLIKE_ASM
386145119Speter		__asm __volatile("				\n\
387145119Speter			cld					\n\
388145119Speter			repne					\n\
389145119Speter			movsb"					:
390145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
391145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
392145119Speter		    "memory", "cc");
393145119Speter#endif
394145119Speter	}
395145119Speter}
396145119Speter
397145119Speterstatic __inline void
398145119Speterbus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
399145119Speter			bus_size_t offset, u_int16_t *addr, size_t count)
400145119Speter{
401216143Sbrucec
402216592Stijl	if (tag == X86_BUS_SPACE_IO) {
403145119Speter		int _port_ = bsh + offset;
404145119Speter#ifdef __GNUCLIKE_ASM
405145119Speter		__asm __volatile("				\n\
406145119Speter			cld					\n\
407145119Speter		1:	inw %w2,%%ax				\n\
408145119Speter			stosw					\n\
409145119Speter			addl $2,%2				\n\
410145119Speter			loop 1b"				:
411145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
412145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
413145119Speter		    "%eax", "memory", "cc");
414145119Speter#endif
415146734Snyan	} else {
416145119Speter		bus_space_handle_t _port_ = bsh + offset;
417145119Speter#ifdef __GNUCLIKE_ASM
418145119Speter		__asm __volatile("				\n\
419145119Speter			cld					\n\
420145119Speter			repne					\n\
421145119Speter			movsw"					:
422145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
423145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
424145119Speter		    "memory", "cc");
425145119Speter#endif
426145119Speter	}
427145119Speter}
428145119Speter
429145119Speterstatic __inline void
430145119Speterbus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
431145119Speter			bus_size_t offset, u_int32_t *addr, size_t count)
432145119Speter{
433216143Sbrucec
434216592Stijl	if (tag == X86_BUS_SPACE_IO) {
435145119Speter		int _port_ = bsh + offset;
436145119Speter#ifdef __GNUCLIKE_ASM
437145119Speter		__asm __volatile("				\n\
438145119Speter			cld					\n\
439145119Speter		1:	inl %w2,%%eax				\n\
440145119Speter			stosl					\n\
441145119Speter			addl $4,%2				\n\
442145119Speter			loop 1b"				:
443145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
444145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
445145119Speter		    "%eax", "memory", "cc");
446145119Speter#endif
447146734Snyan	} else {
448145119Speter		bus_space_handle_t _port_ = bsh + offset;
449145119Speter#ifdef __GNUCLIKE_ASM
450145119Speter		__asm __volatile("				\n\
451145119Speter			cld					\n\
452145119Speter			repne					\n\
453145119Speter			movsl"					:
454145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
455145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
456145119Speter		    "memory", "cc");
457145119Speter#endif
458145119Speter	}
459145119Speter}
460145119Speter
461145119Speter#if 0	/* Cause a link error for bus_space_read_region_8 */
462145119Speter#define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
463145119Speter#endif
464145119Speter
465145119Speter/*
466145119Speter * Write the 1, 2, 4, or 8 byte value `value' to bus space
467145119Speter * described by tag/handle/offset.
468145119Speter */
469145119Speter
470145119Speterstatic __inline void bus_space_write_1(bus_space_tag_t tag,
471145119Speter				       bus_space_handle_t bsh,
472145119Speter				       bus_size_t offset, u_int8_t value);
473145119Speter
474145119Speterstatic __inline void bus_space_write_2(bus_space_tag_t tag,
475145119Speter				       bus_space_handle_t bsh,
476145119Speter				       bus_size_t offset, u_int16_t value);
477145119Speter
478145119Speterstatic __inline void bus_space_write_4(bus_space_tag_t tag,
479145119Speter				       bus_space_handle_t bsh,
480145119Speter				       bus_size_t offset, u_int32_t value);
481145119Speter
482145119Speterstatic __inline void
483145119Speterbus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
484145119Speter		       bus_size_t offset, u_int8_t value)
485145119Speter{
486146734Snyan
487216592Stijl	if (tag == X86_BUS_SPACE_IO)
488145119Speter		outb(bsh + offset, value);
489145119Speter	else
490145119Speter		*(volatile u_int8_t *)(bsh + offset) = value;
491145119Speter}
492145119Speter
493145119Speterstatic __inline void
494145119Speterbus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
495145119Speter		       bus_size_t offset, u_int16_t value)
496145119Speter{
497146734Snyan
498216592Stijl	if (tag == X86_BUS_SPACE_IO)
499145119Speter		outw(bsh + offset, value);
500145119Speter	else
501145119Speter		*(volatile u_int16_t *)(bsh + offset) = value;
502145119Speter}
503145119Speter
504145119Speterstatic __inline void
505145119Speterbus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
506145119Speter		       bus_size_t offset, u_int32_t value)
507145119Speter{
508146734Snyan
509216592Stijl	if (tag == X86_BUS_SPACE_IO)
510145119Speter		outl(bsh + offset, value);
511145119Speter	else
512145119Speter		*(volatile u_int32_t *)(bsh + offset) = value;
513145119Speter}
514145119Speter
515145119Speter#if 0	/* Cause a link error for bus_space_write_8 */
516145119Speter#define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
517145119Speter#endif
518145119Speter
519145119Speter/*
520145119Speter * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
521145119Speter * provided to bus space described by tag/handle/offset.
522145119Speter */
523145119Speter
524145119Speterstatic __inline void bus_space_write_multi_1(bus_space_tag_t tag,
525145119Speter					     bus_space_handle_t bsh,
526145119Speter					     bus_size_t offset,
527145119Speter					     const u_int8_t *addr,
528145119Speter					     size_t count);
529145119Speterstatic __inline void bus_space_write_multi_2(bus_space_tag_t tag,
530145119Speter					     bus_space_handle_t bsh,
531145119Speter					     bus_size_t offset,
532145119Speter					     const u_int16_t *addr,
533145119Speter					     size_t count);
534145119Speter
535145119Speterstatic __inline void bus_space_write_multi_4(bus_space_tag_t tag,
536145119Speter					     bus_space_handle_t bsh,
537145119Speter					     bus_size_t offset,
538145119Speter					     const u_int32_t *addr,
539145119Speter					     size_t count);
540145119Speter
541145119Speterstatic __inline void
542145119Speterbus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
543145119Speter			bus_size_t offset, const u_int8_t *addr, size_t count)
544145119Speter{
545216143Sbrucec
546216592Stijl	if (tag == X86_BUS_SPACE_IO)
547145119Speter		outsb(bsh + offset, addr, count);
548146734Snyan	else {
549145119Speter#ifdef __GNUCLIKE_ASM
550145119Speter		__asm __volatile("				\n\
551145119Speter			cld					\n\
552145119Speter		1:	lodsb					\n\
553145119Speter			movb %%al,(%2)				\n\
554145119Speter			loop 1b"				:
555145119Speter		    "=S" (addr), "=c" (count)			:
556145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
557145119Speter		    "%eax", "memory", "cc");
558145119Speter#endif
559145119Speter	}
560145119Speter}
561145119Speter
562145119Speterstatic __inline void
563145119Speterbus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
564145119Speter			bus_size_t offset, const u_int16_t *addr, size_t count)
565145119Speter{
566216143Sbrucec
567216592Stijl	if (tag == X86_BUS_SPACE_IO)
568145119Speter		outsw(bsh + offset, addr, count);
569146734Snyan	else {
570145119Speter#ifdef __GNUCLIKE_ASM
571145119Speter		__asm __volatile("				\n\
572145119Speter			cld					\n\
573145119Speter		1:	lodsw					\n\
574145119Speter			movw %%ax,(%2)				\n\
575145119Speter			loop 1b"				:
576145119Speter		    "=S" (addr), "=c" (count)			:
577145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
578145119Speter		    "%eax", "memory", "cc");
579145119Speter#endif
580145119Speter	}
581145119Speter}
582145119Speter
583145119Speterstatic __inline void
584145119Speterbus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
585145119Speter			bus_size_t offset, const u_int32_t *addr, size_t count)
586145119Speter{
587216143Sbrucec
588216592Stijl	if (tag == X86_BUS_SPACE_IO)
589145119Speter		outsl(bsh + offset, addr, count);
590146734Snyan	else {
591145119Speter#ifdef __GNUCLIKE_ASM
592145119Speter		__asm __volatile("				\n\
593145119Speter			cld					\n\
594145119Speter		1:	lodsl					\n\
595145119Speter			movl %%eax,(%2)				\n\
596145119Speter			loop 1b"				:
597145119Speter		    "=S" (addr), "=c" (count)			:
598145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
599145119Speter		    "%eax", "memory", "cc");
600145119Speter#endif
601145119Speter	}
602145119Speter}
603145119Speter
604145119Speter#if 0	/* Cause a link error for bus_space_write_multi_8 */
605145119Speter#define	bus_space_write_multi_8(t, h, o, a, c)				\
606145119Speter			!!! bus_space_write_multi_8 unimplemented !!!
607145119Speter#endif
608145119Speter
609145119Speter/*
610145119Speter * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
611145119Speter * to bus space described by tag/handle starting at `offset'.
612145119Speter */
613145119Speter
614145119Speterstatic __inline void bus_space_write_region_1(bus_space_tag_t tag,
615145119Speter					      bus_space_handle_t bsh,
616145119Speter					      bus_size_t offset,
617145119Speter					      const u_int8_t *addr,
618145119Speter					      size_t count);
619145119Speterstatic __inline void bus_space_write_region_2(bus_space_tag_t tag,
620145119Speter					      bus_space_handle_t bsh,
621145119Speter					      bus_size_t offset,
622145119Speter					      const u_int16_t *addr,
623145119Speter					      size_t count);
624145119Speterstatic __inline void bus_space_write_region_4(bus_space_tag_t tag,
625145119Speter					      bus_space_handle_t bsh,
626145119Speter					      bus_size_t offset,
627145119Speter					      const u_int32_t *addr,
628145119Speter					      size_t count);
629145119Speter
630145119Speterstatic __inline void
631145119Speterbus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
632145119Speter			 bus_size_t offset, const u_int8_t *addr, size_t count)
633145119Speter{
634216143Sbrucec
635216592Stijl	if (tag == X86_BUS_SPACE_IO) {
636145119Speter		int _port_ = bsh + offset;
637145119Speter#ifdef __GNUCLIKE_ASM
638145119Speter		__asm __volatile("				\n\
639145119Speter			cld					\n\
640145119Speter		1:	lodsb					\n\
641145119Speter			outb %%al,%w0				\n\
642145119Speter			incl %0					\n\
643145119Speter			loop 1b"				:
644145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
645145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
646145119Speter		    "%eax", "memory", "cc");
647145119Speter#endif
648146734Snyan	} else {
649145119Speter		bus_space_handle_t _port_ = bsh + offset;
650145119Speter#ifdef __GNUCLIKE_ASM
651145119Speter		__asm __volatile("				\n\
652145119Speter			cld					\n\
653145119Speter			repne					\n\
654145119Speter			movsb"					:
655145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
656145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
657145119Speter		    "memory", "cc");
658145119Speter#endif
659145119Speter	}
660145119Speter}
661145119Speter
662145119Speterstatic __inline void
663145119Speterbus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
664145119Speter			 bus_size_t offset, const u_int16_t *addr, size_t count)
665145119Speter{
666216143Sbrucec
667216592Stijl	if (tag == X86_BUS_SPACE_IO) {
668145119Speter		int _port_ = bsh + offset;
669145119Speter#ifdef __GNUCLIKE_ASM
670145119Speter		__asm __volatile("				\n\
671145119Speter			cld					\n\
672145119Speter		1:	lodsw					\n\
673145119Speter			outw %%ax,%w0				\n\
674145119Speter			addl $2,%0				\n\
675145119Speter			loop 1b"				:
676145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
677145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
678145119Speter		    "%eax", "memory", "cc");
679145119Speter#endif
680146734Snyan	} else {
681145119Speter		bus_space_handle_t _port_ = bsh + offset;
682145119Speter#ifdef __GNUCLIKE_ASM
683145119Speter		__asm __volatile("				\n\
684145119Speter			cld					\n\
685145119Speter			repne					\n\
686145119Speter			movsw"					:
687145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
688145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
689145119Speter		    "memory", "cc");
690145119Speter#endif
691145119Speter	}
692145119Speter}
693145119Speter
694145119Speterstatic __inline void
695145119Speterbus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
696145119Speter			 bus_size_t offset, const u_int32_t *addr, size_t count)
697145119Speter{
698216143Sbrucec
699216592Stijl	if (tag == X86_BUS_SPACE_IO) {
700145119Speter		int _port_ = bsh + offset;
701145119Speter#ifdef __GNUCLIKE_ASM
702145119Speter		__asm __volatile("				\n\
703145119Speter			cld					\n\
704145119Speter		1:	lodsl					\n\
705145119Speter			outl %%eax,%w0				\n\
706145119Speter			addl $4,%0				\n\
707145119Speter			loop 1b"				:
708145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
709145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
710145119Speter		    "%eax", "memory", "cc");
711145119Speter#endif
712146734Snyan	} else {
713145119Speter		bus_space_handle_t _port_ = bsh + offset;
714145119Speter#ifdef __GNUCLIKE_ASM
715145119Speter		__asm __volatile("				\n\
716145119Speter			cld					\n\
717145119Speter			repne					\n\
718145119Speter			movsl"					:
719145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
720145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
721145119Speter		    "memory", "cc");
722145119Speter#endif
723145119Speter	}
724145119Speter}
725145119Speter
726145119Speter#if 0	/* Cause a link error for bus_space_write_region_8 */
727145119Speter#define	bus_space_write_region_8					\
728145119Speter			!!! bus_space_write_region_8 unimplemented !!!
729145119Speter#endif
730145119Speter
731145119Speter/*
732145119Speter * Write the 1, 2, 4, or 8 byte value `val' to bus space described
733145119Speter * by tag/handle/offset `count' times.
734145119Speter */
735145119Speter
736145119Speterstatic __inline void bus_space_set_multi_1(bus_space_tag_t tag,
737145119Speter					   bus_space_handle_t bsh,
738145119Speter					   bus_size_t offset,
739145119Speter					   u_int8_t value, size_t count);
740145119Speterstatic __inline void bus_space_set_multi_2(bus_space_tag_t tag,
741145119Speter					   bus_space_handle_t bsh,
742145119Speter					   bus_size_t offset,
743145119Speter					   u_int16_t value, size_t count);
744145119Speterstatic __inline void bus_space_set_multi_4(bus_space_tag_t tag,
745145119Speter					   bus_space_handle_t bsh,
746145119Speter					   bus_size_t offset,
747145119Speter					   u_int32_t value, size_t count);
748145119Speter
749145119Speterstatic __inline void
750145119Speterbus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
751145119Speter		      bus_size_t offset, u_int8_t value, size_t count)
752145119Speter{
753145119Speter	bus_space_handle_t addr = bsh + offset;
754145119Speter
755216592Stijl	if (tag == X86_BUS_SPACE_IO)
756145119Speter		while (count--)
757145119Speter			outb(addr, value);
758145119Speter	else
759145119Speter		while (count--)
760145119Speter			*(volatile u_int8_t *)(addr) = value;
761145119Speter}
762145119Speter
763145119Speterstatic __inline void
764145119Speterbus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
765145119Speter		     bus_size_t offset, u_int16_t value, size_t count)
766145119Speter{
767145119Speter	bus_space_handle_t addr = bsh + offset;
768145119Speter
769216592Stijl	if (tag == X86_BUS_SPACE_IO)
770145119Speter		while (count--)
771145119Speter			outw(addr, value);
772145119Speter	else
773145119Speter		while (count--)
774145119Speter			*(volatile u_int16_t *)(addr) = value;
775145119Speter}
776145119Speter
777145119Speterstatic __inline void
778145119Speterbus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
779145119Speter		      bus_size_t offset, u_int32_t value, size_t count)
780145119Speter{
781145119Speter	bus_space_handle_t addr = bsh + offset;
782145119Speter
783216592Stijl	if (tag == X86_BUS_SPACE_IO)
784145119Speter		while (count--)
785145119Speter			outl(addr, value);
786145119Speter	else
787145119Speter		while (count--)
788145119Speter			*(volatile u_int32_t *)(addr) = value;
789145119Speter}
790145119Speter
791145119Speter#if 0	/* Cause a link error for bus_space_set_multi_8 */
792145119Speter#define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
793145119Speter#endif
794145119Speter
795145119Speter/*
796145119Speter * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
797145119Speter * by tag/handle starting at `offset'.
798145119Speter */
799145119Speter
800145119Speterstatic __inline void bus_space_set_region_1(bus_space_tag_t tag,
801145119Speter					    bus_space_handle_t bsh,
802145119Speter					    bus_size_t offset, u_int8_t value,
803145119Speter					    size_t count);
804145119Speterstatic __inline void bus_space_set_region_2(bus_space_tag_t tag,
805145119Speter					    bus_space_handle_t bsh,
806145119Speter					    bus_size_t offset, u_int16_t value,
807145119Speter					    size_t count);
808145119Speterstatic __inline void bus_space_set_region_4(bus_space_tag_t tag,
809145119Speter					    bus_space_handle_t bsh,
810145119Speter					    bus_size_t offset, u_int32_t value,
811145119Speter					    size_t count);
812145119Speter
813145119Speterstatic __inline void
814145119Speterbus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
815145119Speter		       bus_size_t offset, u_int8_t value, size_t count)
816145119Speter{
817145119Speter	bus_space_handle_t addr = bsh + offset;
818145119Speter
819216592Stijl	if (tag == X86_BUS_SPACE_IO)
820145119Speter		for (; count != 0; count--, addr++)
821145119Speter			outb(addr, value);
822145119Speter	else
823145119Speter		for (; count != 0; count--, addr++)
824145119Speter			*(volatile u_int8_t *)(addr) = value;
825145119Speter}
826145119Speter
827145119Speterstatic __inline void
828145119Speterbus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
829145119Speter		       bus_size_t offset, u_int16_t value, size_t count)
830145119Speter{
831145119Speter	bus_space_handle_t addr = bsh + offset;
832145119Speter
833216592Stijl	if (tag == X86_BUS_SPACE_IO)
834145119Speter		for (; count != 0; count--, addr += 2)
835145119Speter			outw(addr, value);
836145119Speter	else
837145119Speter		for (; count != 0; count--, addr += 2)
838145119Speter			*(volatile u_int16_t *)(addr) = value;
839145119Speter}
840145119Speter
841145119Speterstatic __inline void
842145119Speterbus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
843145119Speter		       bus_size_t offset, u_int32_t value, size_t count)
844145119Speter{
845145119Speter	bus_space_handle_t addr = bsh + offset;
846145119Speter
847216592Stijl	if (tag == X86_BUS_SPACE_IO)
848145119Speter		for (; count != 0; count--, addr += 4)
849145119Speter			outl(addr, value);
850145119Speter	else
851145119Speter		for (; count != 0; count--, addr += 4)
852145119Speter			*(volatile u_int32_t *)(addr) = value;
853145119Speter}
854145119Speter
855145119Speter#if 0	/* Cause a link error for bus_space_set_region_8 */
856145119Speter#define	bus_space_set_region_8	!!! bus_space_set_region_8 unimplemented !!!
857145119Speter#endif
858145119Speter
859145119Speter/*
860145119Speter * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
861145119Speter * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
862145119Speter */
863145119Speter
864145119Speterstatic __inline void bus_space_copy_region_1(bus_space_tag_t tag,
865145119Speter					     bus_space_handle_t bsh1,
866145119Speter					     bus_size_t off1,
867145119Speter					     bus_space_handle_t bsh2,
868145119Speter					     bus_size_t off2, size_t count);
869145119Speter
870145119Speterstatic __inline void bus_space_copy_region_2(bus_space_tag_t tag,
871145119Speter					     bus_space_handle_t bsh1,
872145119Speter					     bus_size_t off1,
873145119Speter					     bus_space_handle_t bsh2,
874145119Speter					     bus_size_t off2, size_t count);
875145119Speter
876145119Speterstatic __inline void bus_space_copy_region_4(bus_space_tag_t tag,
877145119Speter					     bus_space_handle_t bsh1,
878145119Speter					     bus_size_t off1,
879145119Speter					     bus_space_handle_t bsh2,
880145119Speter					     bus_size_t off2, size_t count);
881145119Speter
882145119Speterstatic __inline void
883145119Speterbus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
884145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
885145119Speter			bus_size_t off2, size_t count)
886145119Speter{
887145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
888145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
889145119Speter
890216592Stijl	if (tag == X86_BUS_SPACE_IO) {
891145119Speter		if (addr1 >= addr2) {
892145119Speter			/* src after dest: copy forward */
893145119Speter			for (; count != 0; count--, addr1++, addr2++)
894145119Speter				outb(addr2, inb(addr1));
895145119Speter		} else {
896145119Speter			/* dest after src: copy backwards */
897145119Speter			for (addr1 += (count - 1), addr2 += (count - 1);
898145119Speter			    count != 0; count--, addr1--, addr2--)
899145119Speter				outb(addr2, inb(addr1));
900145119Speter		}
901146734Snyan	} else {
902145119Speter		if (addr1 >= addr2) {
903145119Speter			/* src after dest: copy forward */
904145119Speter			for (; count != 0; count--, addr1++, addr2++)
905145119Speter				*(volatile u_int8_t *)(addr2) =
906145119Speter				    *(volatile u_int8_t *)(addr1);
907145119Speter		} else {
908145119Speter			/* dest after src: copy backwards */
909145119Speter			for (addr1 += (count - 1), addr2 += (count - 1);
910145119Speter			    count != 0; count--, addr1--, addr2--)
911145119Speter				*(volatile u_int8_t *)(addr2) =
912145119Speter				    *(volatile u_int8_t *)(addr1);
913145119Speter		}
914145119Speter	}
915145119Speter}
916145119Speter
917145119Speterstatic __inline void
918145119Speterbus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
919145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
920145119Speter			bus_size_t off2, size_t count)
921145119Speter{
922145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
923145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
924145119Speter
925216592Stijl	if (tag == X86_BUS_SPACE_IO) {
926145119Speter		if (addr1 >= addr2) {
927145119Speter			/* src after dest: copy forward */
928145119Speter			for (; count != 0; count--, addr1 += 2, addr2 += 2)
929145119Speter				outw(addr2, inw(addr1));
930145119Speter		} else {
931145119Speter			/* dest after src: copy backwards */
932145119Speter			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
933145119Speter			    count != 0; count--, addr1 -= 2, addr2 -= 2)
934145119Speter				outw(addr2, inw(addr1));
935145119Speter		}
936146734Snyan	} else {
937145119Speter		if (addr1 >= addr2) {
938145119Speter			/* src after dest: copy forward */
939145119Speter			for (; count != 0; count--, addr1 += 2, addr2 += 2)
940145119Speter				*(volatile u_int16_t *)(addr2) =
941145119Speter				    *(volatile u_int16_t *)(addr1);
942145119Speter		} else {
943145119Speter			/* dest after src: copy backwards */
944145119Speter			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
945145119Speter			    count != 0; count--, addr1 -= 2, addr2 -= 2)
946145119Speter				*(volatile u_int16_t *)(addr2) =
947145119Speter				    *(volatile u_int16_t *)(addr1);
948145119Speter		}
949145119Speter	}
950145119Speter}
951145119Speter
952145119Speterstatic __inline void
953145119Speterbus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
954145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
955145119Speter			bus_size_t off2, size_t count)
956145119Speter{
957145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
958145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
959145119Speter
960216592Stijl	if (tag == X86_BUS_SPACE_IO) {
961145119Speter		if (addr1 >= addr2) {
962145119Speter			/* src after dest: copy forward */
963145119Speter			for (; count != 0; count--, addr1 += 4, addr2 += 4)
964145119Speter				outl(addr2, inl(addr1));
965145119Speter		} else {
966145119Speter			/* dest after src: copy backwards */
967145119Speter			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
968145119Speter			    count != 0; count--, addr1 -= 4, addr2 -= 4)
969145119Speter				outl(addr2, inl(addr1));
970145119Speter		}
971146734Snyan	} else {
972145119Speter		if (addr1 >= addr2) {
973145119Speter			/* src after dest: copy forward */
974145119Speter			for (; count != 0; count--, addr1 += 4, addr2 += 4)
975145119Speter				*(volatile u_int32_t *)(addr2) =
976145119Speter				    *(volatile u_int32_t *)(addr1);
977145119Speter		} else {
978145119Speter			/* dest after src: copy backwards */
979145119Speter			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
980145119Speter			    count != 0; count--, addr1 -= 4, addr2 -= 4)
981145119Speter				*(volatile u_int32_t *)(addr2) =
982145119Speter				    *(volatile u_int32_t *)(addr1);
983145119Speter		}
984145119Speter	}
985145119Speter}
986145119Speter
987145119Speter#if 0	/* Cause a link error for bus_space_copy_8 */
988145119Speter#define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
989145119Speter#endif
990145119Speter
991145119Speter/*
992145119Speter * Bus read/write barrier methods.
993145119Speter *
994145119Speter *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
995145119Speter *			       bus_size_t offset, bus_size_t len, int flags);
996145119Speter *
997145119Speter *
998145119Speter * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
999145119Speter * prevent reordering by the compiler; all Intel x86 processors currently
1000145119Speter * retire operations outside the CPU in program order.
1001145119Speter */
1002145119Speter#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
1003145119Speter#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
1004145119Speter
1005145119Speterstatic __inline void
1006145119Speterbus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
1007145119Speter		  bus_size_t offset __unused, bus_size_t len __unused, int flags)
1008145119Speter{
1009145119Speter#ifdef __GNUCLIKE_ASM
1010145119Speter	if (flags & BUS_SPACE_BARRIER_READ)
1011216592Stijl#ifdef __amd64__
1012145119Speter		__asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
1013216592Stijl#else
1014216592Stijl		__asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
1015216592Stijl#endif
1016145119Speter	else
1017241374Sattilio		__compiler_membar();
1018145119Speter#endif
1019145119Speter}
1020145119Speter
1021156699Speter#ifdef BUS_SPACE_NO_LEGACY
1022156699Speter#undef inb
1023156699Speter#undef outb
1024156699Speter#define inb(a) compiler_error
1025156699Speter#define inw(a) compiler_error
1026156699Speter#define inl(a) compiler_error
1027156699Speter#define outb(a, b) compiler_error
1028156699Speter#define outw(a, b) compiler_error
1029156699Speter#define outl(a, b) compiler_error
1030156699Speter#endif
1031156699Speter
103284593Snyan#include <machine/bus_dma.h>
103348527Simp
103491394Stmm/*
1035216592Stijl * Stream accesses are the same as normal accesses on x86; there are no
103691394Stmm * supported bus systems with an endianess different from the host one.
103791394Stmm */
103891394Stmm#define	bus_space_read_stream_1(t, h, o)	bus_space_read_1((t), (h), (o))
103991394Stmm#define	bus_space_read_stream_2(t, h, o)	bus_space_read_2((t), (h), (o))
104091394Stmm#define	bus_space_read_stream_4(t, h, o)	bus_space_read_4((t), (h), (o))
104191394Stmm
104291394Stmm#define	bus_space_read_multi_stream_1(t, h, o, a, c) \
104391394Stmm	bus_space_read_multi_1((t), (h), (o), (a), (c))
104491394Stmm#define	bus_space_read_multi_stream_2(t, h, o, a, c) \
104591394Stmm	bus_space_read_multi_2((t), (h), (o), (a), (c))
104691394Stmm#define	bus_space_read_multi_stream_4(t, h, o, a, c) \
104791394Stmm	bus_space_read_multi_4((t), (h), (o), (a), (c))
104891394Stmm
104991394Stmm#define	bus_space_write_stream_1(t, h, o, v) \
105091394Stmm	bus_space_write_1((t), (h), (o), (v))
105191394Stmm#define	bus_space_write_stream_2(t, h, o, v) \
105291394Stmm	bus_space_write_2((t), (h), (o), (v))
105391394Stmm#define	bus_space_write_stream_4(t, h, o, v) \
105491394Stmm	bus_space_write_4((t), (h), (o), (v))
105591394Stmm
105691394Stmm#define	bus_space_write_multi_stream_1(t, h, o, a, c) \
105791394Stmm	bus_space_write_multi_1((t), (h), (o), (a), (c))
105891394Stmm#define	bus_space_write_multi_stream_2(t, h, o, a, c) \
105991394Stmm	bus_space_write_multi_2((t), (h), (o), (a), (c))
106091394Stmm#define	bus_space_write_multi_stream_4(t, h, o, a, c) \
106191394Stmm	bus_space_write_multi_4((t), (h), (o), (a), (c))
106291394Stmm
106391394Stmm#define	bus_space_set_multi_stream_1(t, h, o, v, c) \
106491394Stmm	bus_space_set_multi_1((t), (h), (o), (v), (c))
106591394Stmm#define	bus_space_set_multi_stream_2(t, h, o, v, c) \
106691394Stmm	bus_space_set_multi_2((t), (h), (o), (v), (c))
106791394Stmm#define	bus_space_set_multi_stream_4(t, h, o, v, c) \
106891394Stmm	bus_space_set_multi_4((t), (h), (o), (v), (c))
106991394Stmm
107091394Stmm#define	bus_space_read_region_stream_1(t, h, o, a, c) \
107191394Stmm	bus_space_read_region_1((t), (h), (o), (a), (c))
107291394Stmm#define	bus_space_read_region_stream_2(t, h, o, a, c) \
107391394Stmm	bus_space_read_region_2((t), (h), (o), (a), (c))
107491394Stmm#define	bus_space_read_region_stream_4(t, h, o, a, c) \
107591394Stmm	bus_space_read_region_4((t), (h), (o), (a), (c))
107691394Stmm
107791394Stmm#define	bus_space_write_region_stream_1(t, h, o, a, c) \
107891394Stmm	bus_space_write_region_1((t), (h), (o), (a), (c))
107991394Stmm#define	bus_space_write_region_stream_2(t, h, o, a, c) \
108091394Stmm	bus_space_write_region_2((t), (h), (o), (a), (c))
108191394Stmm#define	bus_space_write_region_stream_4(t, h, o, a, c) \
108291394Stmm	bus_space_write_region_4((t), (h), (o), (a), (c))
108391394Stmm
108491394Stmm#define	bus_space_set_region_stream_1(t, h, o, v, c) \
108591394Stmm	bus_space_set_region_1((t), (h), (o), (v), (c))
108691394Stmm#define	bus_space_set_region_stream_2(t, h, o, v, c) \
108791394Stmm	bus_space_set_region_2((t), (h), (o), (v), (c))
108891394Stmm#define	bus_space_set_region_stream_4(t, h, o, v, c) \
108991394Stmm	bus_space_set_region_4((t), (h), (o), (v), (c))
109091394Stmm
109191394Stmm#define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
109291394Stmm	bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
109391394Stmm#define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
109491394Stmm	bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
109591394Stmm#define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
109691394Stmm	bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
109791394Stmm
1098216592Stijl#endif /* _X86_BUS_H_ */
1099