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$
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 *
53145119Speter * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
54145119Speter * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
55145119Speter * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56145119Speter * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
57145119Speter * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
58145119Speter * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
59145119Speter * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60145119Speter * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
61145119Speter * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
62145119Speter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
63145119Speter * POSSIBILITY OF SUCH DAMAGE.
64145119Speter */
65145119Speter
66145119Speter/*-
67145119Speter * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
68145119Speter * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
69145119Speter *
70145119Speter * Redistribution and use in source and binary forms, with or without
71145119Speter * modification, are permitted provided that the following conditions
72145119Speter * are met:
73145119Speter * 1. Redistributions of source code must retain the above copyright
74145119Speter *    notice, this list of conditions and the following disclaimer.
75145119Speter * 2. Redistributions in binary form must reproduce the above copyright
76145119Speter *    notice, this list of conditions and the following disclaimer in the
77145119Speter *    documentation and/or other materials provided with the distribution.
78145119Speter * 3. All advertising materials mentioning features or use of this software
79145119Speter *    must display the following acknowledgement:
80145119Speter *      This product includes software developed by Christopher G. Demetriou
81145119Speter *	for the NetBSD Project.
82145119Speter * 4. The name of the author may not be used to endorse or promote products
83145119Speter *    derived from this software without specific prior written permission
84145119Speter *
85145119Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
86145119Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
87145119Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
88145119Speter * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
89145119Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
90145119Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
91145119Speter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
92145119Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93145119Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
94145119Speter * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95145119Speter */
96145119Speter
97216592Stijl#ifndef _X86_BUS_H_
98216592Stijl#define _X86_BUS_H_
9932517Sgibbs
100145253Simp#include <machine/_bus.h>
101145119Speter#include <machine/cpufunc.h>
102145119Speter
103216592Stijl#ifndef __GNUCLIKE_ASM
104216592Stijl# ifndef lint
105216592Stijl#  error "no assembler code for your compiler"
106216592Stijl# endif
107216592Stijl#endif
108216592Stijl
109145119Speter/*
110216592Stijl * Values for the x86 bus space tag, not to be used directly by MI code.
111145119Speter */
112216592Stijl#define	X86_BUS_SPACE_IO	0	/* space is i/o space */
113216592Stijl#define	X86_BUS_SPACE_MEM	1	/* space is mem space */
114145119Speter
115145119Speter#define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
116145119Speter#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
117145119Speter#define BUS_SPACE_MAXSIZE	0xFFFFFFFF
118145119Speter#define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
119145119Speter#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
120216592Stijl#if defined(__amd64__) || defined(PAE)
121145119Speter#define BUS_SPACE_MAXADDR	0xFFFFFFFFFFFFFFFFULL
122216592Stijl#else
123216592Stijl#define BUS_SPACE_MAXADDR	0xFFFFFFFF
124216592Stijl#endif
125145119Speter
126244193Sjimharris#define BUS_SPACE_INVALID_DATA	(~0)
127145119Speter#define BUS_SPACE_UNRESTRICTED	(~0)
128145119Speter
129145119Speter/*
130145119Speter * Map a region of device bus space into CPU virtual address space.
131145119Speter */
132145119Speter
133286667Smarcelint bus_space_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size,
134286667Smarcel    int flags, bus_space_handle_t *bshp);
135145119Speter
136145119Speter/*
137145119Speter * Unmap a region of device bus space.
138145119Speter */
139145119Speter
140286667Smarcelvoid bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t bsh,
141286667Smarcel    bus_size_t size);
142145119Speter
143145119Speter/*
144145119Speter * Get a new handle for a subregion of an already-mapped area of bus space.
145145119Speter */
146145119Speter
147145119Speterstatic __inline int bus_space_subregion(bus_space_tag_t t,
148145119Speter					bus_space_handle_t bsh,
149145119Speter					bus_size_t offset, bus_size_t size,
150145119Speter					bus_space_handle_t *nbshp);
151145119Speter
152145119Speterstatic __inline int
153145119Speterbus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
154145119Speter		    bus_size_t offset, bus_size_t size __unused,
155145119Speter		    bus_space_handle_t *nbshp)
156145119Speter{
157145119Speter
158145119Speter	*nbshp = bsh + offset;
159145119Speter	return (0);
160145119Speter}
161145119Speter
162145119Speter/*
163145119Speter * Allocate a region of memory that is accessible to devices in bus space.
164145119Speter */
165145119Speter
166145119Speterint	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
167145119Speter			bus_addr_t rend, bus_size_t size, bus_size_t align,
168145119Speter			bus_size_t boundary, int flags, bus_addr_t *addrp,
169145119Speter			bus_space_handle_t *bshp);
170145119Speter
171145119Speter/*
172145119Speter * Free a region of bus space accessible memory.
173145119Speter */
174145119Speter
175145119Speterstatic __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
176145119Speter				    bus_size_t size);
177145119Speter
178145119Speterstatic __inline void
179145119Speterbus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
180145119Speter	       bus_size_t size __unused)
181145119Speter{
182145119Speter}
183145119Speter
184145119Speter
185145119Speter/*
186145119Speter * Read a 1, 2, 4, or 8 byte quantity from bus space
187145119Speter * described by tag/handle/offset.
188145119Speter */
189145119Speterstatic __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
190145119Speter					  bus_space_handle_t handle,
191145119Speter					  bus_size_t offset);
192145119Speter
193145119Speterstatic __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
194145119Speter					   bus_space_handle_t handle,
195145119Speter					   bus_size_t offset);
196145119Speter
197145119Speterstatic __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
198145119Speter					   bus_space_handle_t handle,
199145119Speter					   bus_size_t offset);
200145119Speter
201244193Sjimharris#ifdef __amd64__
202244193Sjimharrisstatic __inline uint64_t bus_space_read_8(bus_space_tag_t tag,
203244193Sjimharris					  bus_space_handle_t handle,
204244193Sjimharris					  bus_size_t offset);
205244193Sjimharris#endif
206244193Sjimharris
207145119Speterstatic __inline u_int8_t
208145119Speterbus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
209145119Speter		 bus_size_t offset)
210145119Speter{
211146734Snyan
212216592Stijl	if (tag == X86_BUS_SPACE_IO)
213145119Speter		return (inb(handle + offset));
214145119Speter	return (*(volatile u_int8_t *)(handle + offset));
215145119Speter}
216145119Speter
217145119Speterstatic __inline u_int16_t
218145119Speterbus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
219145119Speter		 bus_size_t offset)
220145119Speter{
221146734Snyan
222216592Stijl	if (tag == X86_BUS_SPACE_IO)
223145119Speter		return (inw(handle + offset));
224145119Speter	return (*(volatile u_int16_t *)(handle + offset));
225145119Speter}
226145119Speter
227145119Speterstatic __inline u_int32_t
228145119Speterbus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
229145119Speter		 bus_size_t offset)
230145119Speter{
231146734Snyan
232216592Stijl	if (tag == X86_BUS_SPACE_IO)
233145119Speter		return (inl(handle + offset));
234145119Speter	return (*(volatile u_int32_t *)(handle + offset));
235145119Speter}
236145119Speter
237244193Sjimharris#ifdef __amd64__
238244193Sjimharrisstatic __inline uint64_t
239244193Sjimharrisbus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle,
240244193Sjimharris		 bus_size_t offset)
241244193Sjimharris{
242244193Sjimharris
243244193Sjimharris	if (tag == X86_BUS_SPACE_IO) /* No 8 byte IO space access on x86 */
244244193Sjimharris		return (BUS_SPACE_INVALID_DATA);
245244193Sjimharris	return (*(volatile uint64_t *)(handle + offset));
246244193Sjimharris}
247244191Sjimharris#endif
248244191Sjimharris
249145119Speter/*
250145119Speter * Read `count' 1, 2, 4, or 8 byte quantities from bus space
251145119Speter * described by tag/handle/offset and copy into buffer provided.
252145119Speter */
253145119Speterstatic __inline void bus_space_read_multi_1(bus_space_tag_t tag,
254145119Speter					    bus_space_handle_t bsh,
255145119Speter					    bus_size_t offset, u_int8_t *addr,
256145119Speter					    size_t count);
257145119Speter
258145119Speterstatic __inline void bus_space_read_multi_2(bus_space_tag_t tag,
259145119Speter					    bus_space_handle_t bsh,
260145119Speter					    bus_size_t offset, u_int16_t *addr,
261145119Speter					    size_t count);
262145119Speter
263145119Speterstatic __inline void bus_space_read_multi_4(bus_space_tag_t tag,
264145119Speter					    bus_space_handle_t bsh,
265145119Speter					    bus_size_t offset, u_int32_t *addr,
266145119Speter					    size_t count);
267145119Speter
268145119Speterstatic __inline void
269145119Speterbus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
270145119Speter		       bus_size_t offset, u_int8_t *addr, size_t count)
271145119Speter{
272216143Sbrucec
273216592Stijl	if (tag == X86_BUS_SPACE_IO)
274145119Speter		insb(bsh + offset, addr, count);
275146734Snyan	else {
276145119Speter#ifdef __GNUCLIKE_ASM
277145119Speter		__asm __volatile("				\n\
278145119Speter			cld					\n\
279145119Speter		1:	movb (%2),%%al				\n\
280145119Speter			stosb					\n\
281145119Speter			loop 1b"				:
282145119Speter		    "=D" (addr), "=c" (count)			:
283145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
284145119Speter		    "%eax", "memory");
285145119Speter#endif
286145119Speter	}
287145119Speter}
288145119Speter
289145119Speterstatic __inline void
290145119Speterbus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
291145119Speter		       bus_size_t offset, u_int16_t *addr, size_t count)
292145119Speter{
293216143Sbrucec
294216592Stijl	if (tag == X86_BUS_SPACE_IO)
295145119Speter		insw(bsh + offset, addr, count);
296146734Snyan	else {
297145119Speter#ifdef __GNUCLIKE_ASM
298145119Speter		__asm __volatile("				\n\
299145119Speter			cld					\n\
300145119Speter		1:	movw (%2),%%ax				\n\
301145119Speter			stosw					\n\
302145119Speter			loop 1b"				:
303145119Speter		    "=D" (addr), "=c" (count)			:
304145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
305145119Speter		    "%eax", "memory");
306145119Speter#endif
307145119Speter	}
308145119Speter}
309145119Speter
310145119Speterstatic __inline void
311145119Speterbus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
312145119Speter		       bus_size_t offset, u_int32_t *addr, size_t count)
313145119Speter{
314216143Sbrucec
315216592Stijl	if (tag == X86_BUS_SPACE_IO)
316145119Speter		insl(bsh + offset, addr, count);
317146734Snyan	else {
318145119Speter#ifdef __GNUCLIKE_ASM
319145119Speter		__asm __volatile("				\n\
320145119Speter			cld					\n\
321145119Speter		1:	movl (%2),%%eax				\n\
322145119Speter			stosl					\n\
323145119Speter			loop 1b"				:
324145119Speter		    "=D" (addr), "=c" (count)			:
325145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
326145119Speter		    "%eax", "memory");
327145119Speter#endif
328145119Speter	}
329145119Speter}
330145119Speter
331244191Sjimharris#if 0	/* Cause a link error for bus_space_read_multi_8 */
332244191Sjimharris#define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
333244191Sjimharris#endif
334244191Sjimharris
335145119Speter/*
336145119Speter * Read `count' 1, 2, 4, or 8 byte quantities from bus space
337145119Speter * described by tag/handle and starting at `offset' and copy into
338145119Speter * buffer provided.
339145119Speter */
340145119Speterstatic __inline void bus_space_read_region_1(bus_space_tag_t tag,
341145119Speter					     bus_space_handle_t bsh,
342145119Speter					     bus_size_t offset, u_int8_t *addr,
343145119Speter					     size_t count);
344145119Speter
345145119Speterstatic __inline void bus_space_read_region_2(bus_space_tag_t tag,
346145119Speter					     bus_space_handle_t bsh,
347145119Speter					     bus_size_t offset, u_int16_t *addr,
348145119Speter					     size_t count);
349145119Speter
350145119Speterstatic __inline void bus_space_read_region_4(bus_space_tag_t tag,
351145119Speter					     bus_space_handle_t bsh,
352145119Speter					     bus_size_t offset, u_int32_t *addr,
353145119Speter					     size_t count);
354145119Speter
355145119Speter
356145119Speterstatic __inline void
357145119Speterbus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
358145119Speter			bus_size_t offset, u_int8_t *addr, size_t count)
359145119Speter{
360216143Sbrucec
361216592Stijl	if (tag == X86_BUS_SPACE_IO) {
362145119Speter		int _port_ = bsh + offset;
363145119Speter#ifdef __GNUCLIKE_ASM
364145119Speter		__asm __volatile("				\n\
365145119Speter			cld					\n\
366145119Speter		1:	inb %w2,%%al				\n\
367145119Speter			stosb					\n\
368145119Speter			incl %2					\n\
369145119Speter			loop 1b"				:
370145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
371145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
372145119Speter		    "%eax", "memory", "cc");
373145119Speter#endif
374146734Snyan	} else {
375145119Speter		bus_space_handle_t _port_ = bsh + offset;
376145119Speter#ifdef __GNUCLIKE_ASM
377145119Speter		__asm __volatile("				\n\
378145119Speter			cld					\n\
379145119Speter			repne					\n\
380145119Speter			movsb"					:
381145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
382145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
383145119Speter		    "memory", "cc");
384145119Speter#endif
385145119Speter	}
386145119Speter}
387145119Speter
388145119Speterstatic __inline void
389145119Speterbus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
390145119Speter			bus_size_t offset, u_int16_t *addr, size_t count)
391145119Speter{
392216143Sbrucec
393216592Stijl	if (tag == X86_BUS_SPACE_IO) {
394145119Speter		int _port_ = bsh + offset;
395145119Speter#ifdef __GNUCLIKE_ASM
396145119Speter		__asm __volatile("				\n\
397145119Speter			cld					\n\
398145119Speter		1:	inw %w2,%%ax				\n\
399145119Speter			stosw					\n\
400145119Speter			addl $2,%2				\n\
401145119Speter			loop 1b"				:
402145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
403145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
404145119Speter		    "%eax", "memory", "cc");
405145119Speter#endif
406146734Snyan	} else {
407145119Speter		bus_space_handle_t _port_ = bsh + offset;
408145119Speter#ifdef __GNUCLIKE_ASM
409145119Speter		__asm __volatile("				\n\
410145119Speter			cld					\n\
411145119Speter			repne					\n\
412145119Speter			movsw"					:
413145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
414145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
415145119Speter		    "memory", "cc");
416145119Speter#endif
417145119Speter	}
418145119Speter}
419145119Speter
420145119Speterstatic __inline void
421145119Speterbus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
422145119Speter			bus_size_t offset, u_int32_t *addr, size_t count)
423145119Speter{
424216143Sbrucec
425216592Stijl	if (tag == X86_BUS_SPACE_IO) {
426145119Speter		int _port_ = bsh + offset;
427145119Speter#ifdef __GNUCLIKE_ASM
428145119Speter		__asm __volatile("				\n\
429145119Speter			cld					\n\
430145119Speter		1:	inl %w2,%%eax				\n\
431145119Speter			stosl					\n\
432145119Speter			addl $4,%2				\n\
433145119Speter			loop 1b"				:
434145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
435145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
436145119Speter		    "%eax", "memory", "cc");
437145119Speter#endif
438146734Snyan	} else {
439145119Speter		bus_space_handle_t _port_ = bsh + offset;
440145119Speter#ifdef __GNUCLIKE_ASM
441145119Speter		__asm __volatile("				\n\
442145119Speter			cld					\n\
443145119Speter			repne					\n\
444145119Speter			movsl"					:
445145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
446145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
447145119Speter		    "memory", "cc");
448145119Speter#endif
449145119Speter	}
450145119Speter}
451145119Speter
452244191Sjimharris#if 0	/* Cause a link error for bus_space_read_region_8 */
453244191Sjimharris#define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
454244191Sjimharris#endif
455244191Sjimharris
456145119Speter/*
457145119Speter * Write the 1, 2, 4, or 8 byte value `value' to bus space
458145119Speter * described by tag/handle/offset.
459145119Speter */
460145119Speter
461145119Speterstatic __inline void bus_space_write_1(bus_space_tag_t tag,
462145119Speter				       bus_space_handle_t bsh,
463145119Speter				       bus_size_t offset, u_int8_t value);
464145119Speter
465145119Speterstatic __inline void bus_space_write_2(bus_space_tag_t tag,
466145119Speter				       bus_space_handle_t bsh,
467145119Speter				       bus_size_t offset, u_int16_t value);
468145119Speter
469145119Speterstatic __inline void bus_space_write_4(bus_space_tag_t tag,
470145119Speter				       bus_space_handle_t bsh,
471145119Speter				       bus_size_t offset, u_int32_t value);
472145119Speter
473244193Sjimharris#ifdef __amd64__
474244193Sjimharrisstatic __inline void bus_space_write_8(bus_space_tag_t tag,
475244193Sjimharris				       bus_space_handle_t bsh,
476244193Sjimharris				       bus_size_t offset, uint64_t value);
477244193Sjimharris#endif
478244193Sjimharris
479145119Speterstatic __inline void
480145119Speterbus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
481145119Speter		       bus_size_t offset, u_int8_t value)
482145119Speter{
483146734Snyan
484216592Stijl	if (tag == X86_BUS_SPACE_IO)
485145119Speter		outb(bsh + offset, value);
486145119Speter	else
487145119Speter		*(volatile u_int8_t *)(bsh + offset) = value;
488145119Speter}
489145119Speter
490145119Speterstatic __inline void
491145119Speterbus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
492145119Speter		       bus_size_t offset, u_int16_t value)
493145119Speter{
494146734Snyan
495216592Stijl	if (tag == X86_BUS_SPACE_IO)
496145119Speter		outw(bsh + offset, value);
497145119Speter	else
498145119Speter		*(volatile u_int16_t *)(bsh + offset) = value;
499145119Speter}
500145119Speter
501145119Speterstatic __inline void
502145119Speterbus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
503145119Speter		       bus_size_t offset, u_int32_t value)
504145119Speter{
505146734Snyan
506216592Stijl	if (tag == X86_BUS_SPACE_IO)
507145119Speter		outl(bsh + offset, value);
508145119Speter	else
509145119Speter		*(volatile u_int32_t *)(bsh + offset) = value;
510145119Speter}
511145119Speter
512244193Sjimharris#ifdef __amd64__
513244193Sjimharrisstatic __inline void
514244193Sjimharrisbus_space_write_8(bus_space_tag_t tag, bus_space_handle_t bsh,
515244193Sjimharris		  bus_size_t offset, uint64_t value)
516244193Sjimharris{
517244193Sjimharris
518244193Sjimharris	if (tag == X86_BUS_SPACE_IO) /* No 8 byte IO space access on x86 */
519244193Sjimharris		return;
520244193Sjimharris	else
521244193Sjimharris		*(volatile uint64_t *)(bsh + offset) = value;
522244193Sjimharris}
523244191Sjimharris#endif
524244191Sjimharris
525145119Speter/*
526145119Speter * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
527145119Speter * provided to bus space described by tag/handle/offset.
528145119Speter */
529145119Speter
530145119Speterstatic __inline void bus_space_write_multi_1(bus_space_tag_t tag,
531145119Speter					     bus_space_handle_t bsh,
532145119Speter					     bus_size_t offset,
533145119Speter					     const u_int8_t *addr,
534145119Speter					     size_t count);
535145119Speterstatic __inline void bus_space_write_multi_2(bus_space_tag_t tag,
536145119Speter					     bus_space_handle_t bsh,
537145119Speter					     bus_size_t offset,
538145119Speter					     const u_int16_t *addr,
539145119Speter					     size_t count);
540145119Speter
541145119Speterstatic __inline void bus_space_write_multi_4(bus_space_tag_t tag,
542145119Speter					     bus_space_handle_t bsh,
543145119Speter					     bus_size_t offset,
544145119Speter					     const u_int32_t *addr,
545145119Speter					     size_t count);
546145119Speter
547145119Speterstatic __inline void
548145119Speterbus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
549145119Speter			bus_size_t offset, const u_int8_t *addr, size_t count)
550145119Speter{
551216143Sbrucec
552216592Stijl	if (tag == X86_BUS_SPACE_IO)
553145119Speter		outsb(bsh + offset, addr, count);
554146734Snyan	else {
555145119Speter#ifdef __GNUCLIKE_ASM
556145119Speter		__asm __volatile("				\n\
557145119Speter			cld					\n\
558145119Speter		1:	lodsb					\n\
559145119Speter			movb %%al,(%2)				\n\
560145119Speter			loop 1b"				:
561145119Speter		    "=S" (addr), "=c" (count)			:
562145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
563145119Speter		    "%eax", "memory", "cc");
564145119Speter#endif
565145119Speter	}
566145119Speter}
567145119Speter
568145119Speterstatic __inline void
569145119Speterbus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
570145119Speter			bus_size_t offset, const u_int16_t *addr, size_t count)
571145119Speter{
572216143Sbrucec
573216592Stijl	if (tag == X86_BUS_SPACE_IO)
574145119Speter		outsw(bsh + offset, addr, count);
575146734Snyan	else {
576145119Speter#ifdef __GNUCLIKE_ASM
577145119Speter		__asm __volatile("				\n\
578145119Speter			cld					\n\
579145119Speter		1:	lodsw					\n\
580145119Speter			movw %%ax,(%2)				\n\
581145119Speter			loop 1b"				:
582145119Speter		    "=S" (addr), "=c" (count)			:
583145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
584145119Speter		    "%eax", "memory", "cc");
585145119Speter#endif
586145119Speter	}
587145119Speter}
588145119Speter
589145119Speterstatic __inline void
590145119Speterbus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
591145119Speter			bus_size_t offset, const u_int32_t *addr, size_t count)
592145119Speter{
593216143Sbrucec
594216592Stijl	if (tag == X86_BUS_SPACE_IO)
595145119Speter		outsl(bsh + offset, addr, count);
596146734Snyan	else {
597145119Speter#ifdef __GNUCLIKE_ASM
598145119Speter		__asm __volatile("				\n\
599145119Speter			cld					\n\
600145119Speter		1:	lodsl					\n\
601145119Speter			movl %%eax,(%2)				\n\
602145119Speter			loop 1b"				:
603145119Speter		    "=S" (addr), "=c" (count)			:
604145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
605145119Speter		    "%eax", "memory", "cc");
606145119Speter#endif
607145119Speter	}
608145119Speter}
609145119Speter
610244191Sjimharris#if 0	/* Cause a link error for bus_space_write_multi_8 */
611244191Sjimharris#define	bus_space_write_multi_8(t, h, o, a, c)				\
612244191Sjimharris			!!! bus_space_write_multi_8 unimplemented !!!
613244191Sjimharris#endif
614244191Sjimharris
615145119Speter/*
616145119Speter * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
617145119Speter * to bus space described by tag/handle starting at `offset'.
618145119Speter */
619145119Speter
620145119Speterstatic __inline void bus_space_write_region_1(bus_space_tag_t tag,
621145119Speter					      bus_space_handle_t bsh,
622145119Speter					      bus_size_t offset,
623145119Speter					      const u_int8_t *addr,
624145119Speter					      size_t count);
625145119Speterstatic __inline void bus_space_write_region_2(bus_space_tag_t tag,
626145119Speter					      bus_space_handle_t bsh,
627145119Speter					      bus_size_t offset,
628145119Speter					      const u_int16_t *addr,
629145119Speter					      size_t count);
630145119Speterstatic __inline void bus_space_write_region_4(bus_space_tag_t tag,
631145119Speter					      bus_space_handle_t bsh,
632145119Speter					      bus_size_t offset,
633145119Speter					      const u_int32_t *addr,
634145119Speter					      size_t count);
635145119Speter
636145119Speterstatic __inline void
637145119Speterbus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
638145119Speter			 bus_size_t offset, const u_int8_t *addr, size_t count)
639145119Speter{
640216143Sbrucec
641216592Stijl	if (tag == X86_BUS_SPACE_IO) {
642145119Speter		int _port_ = bsh + offset;
643145119Speter#ifdef __GNUCLIKE_ASM
644145119Speter		__asm __volatile("				\n\
645145119Speter			cld					\n\
646145119Speter		1:	lodsb					\n\
647145119Speter			outb %%al,%w0				\n\
648145119Speter			incl %0					\n\
649145119Speter			loop 1b"				:
650145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
651145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
652145119Speter		    "%eax", "memory", "cc");
653145119Speter#endif
654146734Snyan	} else {
655145119Speter		bus_space_handle_t _port_ = bsh + offset;
656145119Speter#ifdef __GNUCLIKE_ASM
657145119Speter		__asm __volatile("				\n\
658145119Speter			cld					\n\
659145119Speter			repne					\n\
660145119Speter			movsb"					:
661145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
662145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
663145119Speter		    "memory", "cc");
664145119Speter#endif
665145119Speter	}
666145119Speter}
667145119Speter
668145119Speterstatic __inline void
669145119Speterbus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
670145119Speter			 bus_size_t offset, const u_int16_t *addr, size_t count)
671145119Speter{
672216143Sbrucec
673216592Stijl	if (tag == X86_BUS_SPACE_IO) {
674145119Speter		int _port_ = bsh + offset;
675145119Speter#ifdef __GNUCLIKE_ASM
676145119Speter		__asm __volatile("				\n\
677145119Speter			cld					\n\
678145119Speter		1:	lodsw					\n\
679145119Speter			outw %%ax,%w0				\n\
680145119Speter			addl $2,%0				\n\
681145119Speter			loop 1b"				:
682145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
683145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
684145119Speter		    "%eax", "memory", "cc");
685145119Speter#endif
686146734Snyan	} else {
687145119Speter		bus_space_handle_t _port_ = bsh + offset;
688145119Speter#ifdef __GNUCLIKE_ASM
689145119Speter		__asm __volatile("				\n\
690145119Speter			cld					\n\
691145119Speter			repne					\n\
692145119Speter			movsw"					:
693145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
694145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
695145119Speter		    "memory", "cc");
696145119Speter#endif
697145119Speter	}
698145119Speter}
699145119Speter
700145119Speterstatic __inline void
701145119Speterbus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
702145119Speter			 bus_size_t offset, const u_int32_t *addr, size_t count)
703145119Speter{
704216143Sbrucec
705216592Stijl	if (tag == X86_BUS_SPACE_IO) {
706145119Speter		int _port_ = bsh + offset;
707145119Speter#ifdef __GNUCLIKE_ASM
708145119Speter		__asm __volatile("				\n\
709145119Speter			cld					\n\
710145119Speter		1:	lodsl					\n\
711145119Speter			outl %%eax,%w0				\n\
712145119Speter			addl $4,%0				\n\
713145119Speter			loop 1b"				:
714145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
715145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
716145119Speter		    "%eax", "memory", "cc");
717145119Speter#endif
718146734Snyan	} else {
719145119Speter		bus_space_handle_t _port_ = bsh + offset;
720145119Speter#ifdef __GNUCLIKE_ASM
721145119Speter		__asm __volatile("				\n\
722145119Speter			cld					\n\
723145119Speter			repne					\n\
724145119Speter			movsl"					:
725145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
726145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
727145119Speter		    "memory", "cc");
728145119Speter#endif
729145119Speter	}
730145119Speter}
731145119Speter
732244191Sjimharris#if 0	/* Cause a link error for bus_space_write_region_8 */
733244191Sjimharris#define	bus_space_write_region_8					\
734244191Sjimharris			!!! bus_space_write_region_8 unimplemented !!!
735244191Sjimharris#endif
736244191Sjimharris
737145119Speter/*
738145119Speter * Write the 1, 2, 4, or 8 byte value `val' to bus space described
739145119Speter * by tag/handle/offset `count' times.
740145119Speter */
741145119Speter
742145119Speterstatic __inline void bus_space_set_multi_1(bus_space_tag_t tag,
743145119Speter					   bus_space_handle_t bsh,
744145119Speter					   bus_size_t offset,
745145119Speter					   u_int8_t value, size_t count);
746145119Speterstatic __inline void bus_space_set_multi_2(bus_space_tag_t tag,
747145119Speter					   bus_space_handle_t bsh,
748145119Speter					   bus_size_t offset,
749145119Speter					   u_int16_t value, size_t count);
750145119Speterstatic __inline void bus_space_set_multi_4(bus_space_tag_t tag,
751145119Speter					   bus_space_handle_t bsh,
752145119Speter					   bus_size_t offset,
753145119Speter					   u_int32_t value, size_t count);
754145119Speter
755145119Speterstatic __inline void
756145119Speterbus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
757145119Speter		      bus_size_t offset, u_int8_t value, size_t count)
758145119Speter{
759145119Speter	bus_space_handle_t addr = bsh + offset;
760145119Speter
761216592Stijl	if (tag == X86_BUS_SPACE_IO)
762145119Speter		while (count--)
763145119Speter			outb(addr, value);
764145119Speter	else
765145119Speter		while (count--)
766145119Speter			*(volatile u_int8_t *)(addr) = value;
767145119Speter}
768145119Speter
769145119Speterstatic __inline void
770145119Speterbus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
771145119Speter		     bus_size_t offset, u_int16_t value, size_t count)
772145119Speter{
773145119Speter	bus_space_handle_t addr = bsh + offset;
774145119Speter
775216592Stijl	if (tag == X86_BUS_SPACE_IO)
776145119Speter		while (count--)
777145119Speter			outw(addr, value);
778145119Speter	else
779145119Speter		while (count--)
780145119Speter			*(volatile u_int16_t *)(addr) = value;
781145119Speter}
782145119Speter
783145119Speterstatic __inline void
784145119Speterbus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
785145119Speter		      bus_size_t offset, u_int32_t value, size_t count)
786145119Speter{
787145119Speter	bus_space_handle_t addr = bsh + offset;
788145119Speter
789216592Stijl	if (tag == X86_BUS_SPACE_IO)
790145119Speter		while (count--)
791145119Speter			outl(addr, value);
792145119Speter	else
793145119Speter		while (count--)
794145119Speter			*(volatile u_int32_t *)(addr) = value;
795145119Speter}
796145119Speter
797244191Sjimharris#if 0	/* Cause a link error for bus_space_set_multi_8 */
798244191Sjimharris#define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
799244191Sjimharris#endif
800244191Sjimharris
801145119Speter/*
802145119Speter * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
803145119Speter * by tag/handle starting at `offset'.
804145119Speter */
805145119Speter
806145119Speterstatic __inline void bus_space_set_region_1(bus_space_tag_t tag,
807145119Speter					    bus_space_handle_t bsh,
808145119Speter					    bus_size_t offset, u_int8_t value,
809145119Speter					    size_t count);
810145119Speterstatic __inline void bus_space_set_region_2(bus_space_tag_t tag,
811145119Speter					    bus_space_handle_t bsh,
812145119Speter					    bus_size_t offset, u_int16_t value,
813145119Speter					    size_t count);
814145119Speterstatic __inline void bus_space_set_region_4(bus_space_tag_t tag,
815145119Speter					    bus_space_handle_t bsh,
816145119Speter					    bus_size_t offset, u_int32_t value,
817145119Speter					    size_t count);
818145119Speter
819145119Speterstatic __inline void
820145119Speterbus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
821145119Speter		       bus_size_t offset, u_int8_t value, size_t count)
822145119Speter{
823145119Speter	bus_space_handle_t addr = bsh + offset;
824145119Speter
825216592Stijl	if (tag == X86_BUS_SPACE_IO)
826145119Speter		for (; count != 0; count--, addr++)
827145119Speter			outb(addr, value);
828145119Speter	else
829145119Speter		for (; count != 0; count--, addr++)
830145119Speter			*(volatile u_int8_t *)(addr) = value;
831145119Speter}
832145119Speter
833145119Speterstatic __inline void
834145119Speterbus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
835145119Speter		       bus_size_t offset, u_int16_t value, size_t count)
836145119Speter{
837145119Speter	bus_space_handle_t addr = bsh + offset;
838145119Speter
839216592Stijl	if (tag == X86_BUS_SPACE_IO)
840145119Speter		for (; count != 0; count--, addr += 2)
841145119Speter			outw(addr, value);
842145119Speter	else
843145119Speter		for (; count != 0; count--, addr += 2)
844145119Speter			*(volatile u_int16_t *)(addr) = value;
845145119Speter}
846145119Speter
847145119Speterstatic __inline void
848145119Speterbus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
849145119Speter		       bus_size_t offset, u_int32_t value, size_t count)
850145119Speter{
851145119Speter	bus_space_handle_t addr = bsh + offset;
852145119Speter
853216592Stijl	if (tag == X86_BUS_SPACE_IO)
854145119Speter		for (; count != 0; count--, addr += 4)
855145119Speter			outl(addr, value);
856145119Speter	else
857145119Speter		for (; count != 0; count--, addr += 4)
858145119Speter			*(volatile u_int32_t *)(addr) = value;
859145119Speter}
860145119Speter
861244191Sjimharris#if 0	/* Cause a link error for bus_space_set_region_8 */
862244191Sjimharris#define	bus_space_set_region_8	!!! bus_space_set_region_8 unimplemented !!!
863244191Sjimharris#endif
864244191Sjimharris
865145119Speter/*
866145119Speter * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
867145119Speter * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
868145119Speter */
869145119Speter
870145119Speterstatic __inline void bus_space_copy_region_1(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_2(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 bus_space_copy_region_4(bus_space_tag_t tag,
883145119Speter					     bus_space_handle_t bsh1,
884145119Speter					     bus_size_t off1,
885145119Speter					     bus_space_handle_t bsh2,
886145119Speter					     bus_size_t off2, size_t count);
887145119Speter
888145119Speterstatic __inline void
889145119Speterbus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
890145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
891145119Speter			bus_size_t off2, size_t count)
892145119Speter{
893145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
894145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
895145119Speter
896216592Stijl	if (tag == X86_BUS_SPACE_IO) {
897145119Speter		if (addr1 >= addr2) {
898145119Speter			/* src after dest: copy forward */
899145119Speter			for (; count != 0; count--, addr1++, addr2++)
900145119Speter				outb(addr2, inb(addr1));
901145119Speter		} else {
902145119Speter			/* dest after src: copy backwards */
903145119Speter			for (addr1 += (count - 1), addr2 += (count - 1);
904145119Speter			    count != 0; count--, addr1--, addr2--)
905145119Speter				outb(addr2, inb(addr1));
906145119Speter		}
907146734Snyan	} else {
908145119Speter		if (addr1 >= addr2) {
909145119Speter			/* src after dest: copy forward */
910145119Speter			for (; count != 0; count--, addr1++, addr2++)
911145119Speter				*(volatile u_int8_t *)(addr2) =
912145119Speter				    *(volatile u_int8_t *)(addr1);
913145119Speter		} else {
914145119Speter			/* dest after src: copy backwards */
915145119Speter			for (addr1 += (count - 1), addr2 += (count - 1);
916145119Speter			    count != 0; count--, addr1--, addr2--)
917145119Speter				*(volatile u_int8_t *)(addr2) =
918145119Speter				    *(volatile u_int8_t *)(addr1);
919145119Speter		}
920145119Speter	}
921145119Speter}
922145119Speter
923145119Speterstatic __inline void
924145119Speterbus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
925145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
926145119Speter			bus_size_t off2, size_t count)
927145119Speter{
928145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
929145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
930145119Speter
931216592Stijl	if (tag == X86_BUS_SPACE_IO) {
932145119Speter		if (addr1 >= addr2) {
933145119Speter			/* src after dest: copy forward */
934145119Speter			for (; count != 0; count--, addr1 += 2, addr2 += 2)
935145119Speter				outw(addr2, inw(addr1));
936145119Speter		} else {
937145119Speter			/* dest after src: copy backwards */
938145119Speter			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
939145119Speter			    count != 0; count--, addr1 -= 2, addr2 -= 2)
940145119Speter				outw(addr2, inw(addr1));
941145119Speter		}
942146734Snyan	} else {
943145119Speter		if (addr1 >= addr2) {
944145119Speter			/* src after dest: copy forward */
945145119Speter			for (; count != 0; count--, addr1 += 2, addr2 += 2)
946145119Speter				*(volatile u_int16_t *)(addr2) =
947145119Speter				    *(volatile u_int16_t *)(addr1);
948145119Speter		} else {
949145119Speter			/* dest after src: copy backwards */
950145119Speter			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
951145119Speter			    count != 0; count--, addr1 -= 2, addr2 -= 2)
952145119Speter				*(volatile u_int16_t *)(addr2) =
953145119Speter				    *(volatile u_int16_t *)(addr1);
954145119Speter		}
955145119Speter	}
956145119Speter}
957145119Speter
958145119Speterstatic __inline void
959145119Speterbus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
960145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
961145119Speter			bus_size_t off2, size_t count)
962145119Speter{
963145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
964145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
965145119Speter
966216592Stijl	if (tag == X86_BUS_SPACE_IO) {
967145119Speter		if (addr1 >= addr2) {
968145119Speter			/* src after dest: copy forward */
969145119Speter			for (; count != 0; count--, addr1 += 4, addr2 += 4)
970145119Speter				outl(addr2, inl(addr1));
971145119Speter		} else {
972145119Speter			/* dest after src: copy backwards */
973145119Speter			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
974145119Speter			    count != 0; count--, addr1 -= 4, addr2 -= 4)
975145119Speter				outl(addr2, inl(addr1));
976145119Speter		}
977146734Snyan	} else {
978145119Speter		if (addr1 >= addr2) {
979145119Speter			/* src after dest: copy forward */
980145119Speter			for (; count != 0; count--, addr1 += 4, addr2 += 4)
981145119Speter				*(volatile u_int32_t *)(addr2) =
982145119Speter				    *(volatile u_int32_t *)(addr1);
983145119Speter		} else {
984145119Speter			/* dest after src: copy backwards */
985145119Speter			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
986145119Speter			    count != 0; count--, addr1 -= 4, addr2 -= 4)
987145119Speter				*(volatile u_int32_t *)(addr2) =
988145119Speter				    *(volatile u_int32_t *)(addr1);
989145119Speter		}
990145119Speter	}
991145119Speter}
992145119Speter
993244191Sjimharris#if 0	/* Cause a link error for bus_space_copy_8 */
994244191Sjimharris#define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
995244191Sjimharris#endif
996244191Sjimharris
997145119Speter/*
998145119Speter * Bus read/write barrier methods.
999145119Speter *
1000145119Speter *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
1001145119Speter *			       bus_size_t offset, bus_size_t len, int flags);
1002145119Speter *
1003145119Speter *
1004145119Speter * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
1005145119Speter * prevent reordering by the compiler; all Intel x86 processors currently
1006145119Speter * retire operations outside the CPU in program order.
1007145119Speter */
1008145119Speter#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
1009145119Speter#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
1010145119Speter
1011145119Speterstatic __inline void
1012145119Speterbus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
1013145119Speter		  bus_size_t offset __unused, bus_size_t len __unused, int flags)
1014145119Speter{
1015145119Speter#ifdef __GNUCLIKE_ASM
1016145119Speter	if (flags & BUS_SPACE_BARRIER_READ)
1017216592Stijl#ifdef __amd64__
1018145119Speter		__asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
1019216592Stijl#else
1020216592Stijl		__asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
1021216592Stijl#endif
1022145119Speter	else
1023241374Sattilio		__compiler_membar();
1024145119Speter#endif
1025145119Speter}
1026145119Speter
1027156699Speter#ifdef BUS_SPACE_NO_LEGACY
1028156699Speter#undef inb
1029156699Speter#undef outb
1030156699Speter#define inb(a) compiler_error
1031156699Speter#define inw(a) compiler_error
1032156699Speter#define inl(a) compiler_error
1033156699Speter#define outb(a, b) compiler_error
1034156699Speter#define outw(a, b) compiler_error
1035156699Speter#define outl(a, b) compiler_error
1036156699Speter#endif
1037156699Speter
103884593Snyan#include <machine/bus_dma.h>
103948527Simp
104091394Stmm/*
1041216592Stijl * Stream accesses are the same as normal accesses on x86; there are no
104291394Stmm * supported bus systems with an endianess different from the host one.
104391394Stmm */
104491394Stmm#define	bus_space_read_stream_1(t, h, o)	bus_space_read_1((t), (h), (o))
104591394Stmm#define	bus_space_read_stream_2(t, h, o)	bus_space_read_2((t), (h), (o))
104691394Stmm#define	bus_space_read_stream_4(t, h, o)	bus_space_read_4((t), (h), (o))
104791394Stmm
104891394Stmm#define	bus_space_read_multi_stream_1(t, h, o, a, c) \
104991394Stmm	bus_space_read_multi_1((t), (h), (o), (a), (c))
105091394Stmm#define	bus_space_read_multi_stream_2(t, h, o, a, c) \
105191394Stmm	bus_space_read_multi_2((t), (h), (o), (a), (c))
105291394Stmm#define	bus_space_read_multi_stream_4(t, h, o, a, c) \
105391394Stmm	bus_space_read_multi_4((t), (h), (o), (a), (c))
105491394Stmm
105591394Stmm#define	bus_space_write_stream_1(t, h, o, v) \
105691394Stmm	bus_space_write_1((t), (h), (o), (v))
105791394Stmm#define	bus_space_write_stream_2(t, h, o, v) \
105891394Stmm	bus_space_write_2((t), (h), (o), (v))
105991394Stmm#define	bus_space_write_stream_4(t, h, o, v) \
106091394Stmm	bus_space_write_4((t), (h), (o), (v))
106191394Stmm
106291394Stmm#define	bus_space_write_multi_stream_1(t, h, o, a, c) \
106391394Stmm	bus_space_write_multi_1((t), (h), (o), (a), (c))
106491394Stmm#define	bus_space_write_multi_stream_2(t, h, o, a, c) \
106591394Stmm	bus_space_write_multi_2((t), (h), (o), (a), (c))
106691394Stmm#define	bus_space_write_multi_stream_4(t, h, o, a, c) \
106791394Stmm	bus_space_write_multi_4((t), (h), (o), (a), (c))
106891394Stmm
106991394Stmm#define	bus_space_set_multi_stream_1(t, h, o, v, c) \
107091394Stmm	bus_space_set_multi_1((t), (h), (o), (v), (c))
107191394Stmm#define	bus_space_set_multi_stream_2(t, h, o, v, c) \
107291394Stmm	bus_space_set_multi_2((t), (h), (o), (v), (c))
107391394Stmm#define	bus_space_set_multi_stream_4(t, h, o, v, c) \
107491394Stmm	bus_space_set_multi_4((t), (h), (o), (v), (c))
107591394Stmm
107691394Stmm#define	bus_space_read_region_stream_1(t, h, o, a, c) \
107791394Stmm	bus_space_read_region_1((t), (h), (o), (a), (c))
107891394Stmm#define	bus_space_read_region_stream_2(t, h, o, a, c) \
107991394Stmm	bus_space_read_region_2((t), (h), (o), (a), (c))
108091394Stmm#define	bus_space_read_region_stream_4(t, h, o, a, c) \
108191394Stmm	bus_space_read_region_4((t), (h), (o), (a), (c))
108291394Stmm
108391394Stmm#define	bus_space_write_region_stream_1(t, h, o, a, c) \
108491394Stmm	bus_space_write_region_1((t), (h), (o), (a), (c))
108591394Stmm#define	bus_space_write_region_stream_2(t, h, o, a, c) \
108691394Stmm	bus_space_write_region_2((t), (h), (o), (a), (c))
108791394Stmm#define	bus_space_write_region_stream_4(t, h, o, a, c) \
108891394Stmm	bus_space_write_region_4((t), (h), (o), (a), (c))
108991394Stmm
109091394Stmm#define	bus_space_set_region_stream_1(t, h, o, v, c) \
109191394Stmm	bus_space_set_region_1((t), (h), (o), (v), (c))
109291394Stmm#define	bus_space_set_region_stream_2(t, h, o, v, c) \
109391394Stmm	bus_space_set_region_2((t), (h), (o), (v), (c))
109491394Stmm#define	bus_space_set_region_stream_4(t, h, o, v, c) \
109591394Stmm	bus_space_set_region_4((t), (h), (o), (v), (c))
109691394Stmm
109791394Stmm#define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
109891394Stmm	bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
109991394Stmm#define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
1100